sql >> Base de Datos >  >> NoSQL >> MongoDB

Analógico para grupo concat en sql

Según los comentarios hasta ahora, no está claro qué está agrupando o qué quiere como resultado final, aparte de decir que desea que sus fechas se concatenen en algo como "solo el día" sin horas ni minutos juntos. Es de suponer que desea esos días distintos para algún propósito.

Hay varios Operadores de fecha en la tubería que puede usar en las fechas, y es el $concat operador también. Lamentablemente, todos los operadores de fecha producir un número entero como resultado, y para el tipo de cadena de fecha que desee, $concat solo funcionará con cadenas. El otro problema es que no puedes lanzar el entero en un tipo de cadena dentro de la agregación.

Pero tú puedes use subdocumentos, aquí solo trabajaremos con la fecha:

db.record.aggregate([
    // Unwind the array to work with it
    {$unwind: "$date"},

    // project into our new 'day' document
    {$project:{ 
        day: { 
            year: {$year: "$date"},
            month: {$month: "$date"}, 
            day: {$dayOfMonth: "$date"}
        }
     } },

     // optionalally sort if date order is important [ oldest -> newest ] 
     {$sort: { "day.year": -1, "day.month": -1, "day.day": -1}},

     // Wind back unique values into the array
     {$group: {_id:"$_id", days: {$addToSet: "$day"} }}
])

Por lo tanto, no es una cadena, pero se puede posprocesar fácilmente en una, pero lo más importante es que se agrupa y se puede ordenar.

Los principios siguen siendo los mismos si desea las dates únicas de esta manera como una matriz al final o si desea agrupar los totales por esas fechas. Por lo tanto, tenga en cuenta principalmente las partes $unwind y $project utilizando los operadores de fecha.

--EDITAR--

Con agradecimiento a la comunidad como se muestra en esta publicación existe este indocumentado comportamiento de $substr , en el que los enteros se pueden convertir como cadenas.

db.record.aggregate([
    // Unwind the array to work with it
    {$unwind: "$date"},

    // project into our new 'day' document
    {$project:{ 
        day: { 
            year: {$year: "$date"},
            month: {$month: "$date"}, 
            day: {$dayOfMonth: "$date"}
        }
     } },

     // optionalally sort if date order is important [ oldest -> newest ] 
     {$sort: { "day.year": -1, "day.month": -1, "day.day": -1}},

     // now we are going to project to a string ** magic @heinob **
     {$project: { 
         day: {$concat: [
             {$substr: [ "$day.year", 0, 4 ]},
             "-",
             {$substr: [ "$day.month", 0, 2 ]},
             "-",
             {$substr: [ "$day.day", 0, 2 ]}
         ]}
     }},

     // Wind back unique values into the array
     {$group: {_id:"$_id", days: {$addToSet: "$day"} }}
])

Y ahora los days son cuerdas. Como señalé antes, si el orden es importante para usted, entonces el mejor enfoque es proyectar en un tipo de documento como se ha hecho y ordenar las claves numéricas. Naturalmente, el $proyecto que transforma la fecha se puede enrollar en la etapa de $grupo por razones de brevedad, que es probablemente lo que desea hacer cuando trabaja con todo el documento.