MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Analógico para concat de grupo em sql


De acordo com os comentários até agora, não está claro o que você está agrupando ou o que deseja como resultado final, além de dizer que deseja que suas datas sejam concatenadas em algo como "apenas o dia" sem horas ou minutos juntos. Presumivelmente, você quer esses dias distintos para algum propósito.

Existem vários Operadores de data no pipeline você pode usar em datas, e é o $concat operador também. Infelizmente, todos os Operadores de Data produza um inteiro como resultado e, para o tipo de string de data que você deseja, $concat só funcionará com strings. O outro problema é que você não pode conjurar o inteiro em um tipo de string dentro da agregação.

Mas você pode use subdocumentos, aqui vamos trabalhar apenas com a data:
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"} }}
])

Portanto, não é uma string, mas pode ser facilmente pós-processada em uma, mas o mais importante é agrupada e classificável.

Os princípios permanecem os mesmos se você quiser as dates exclusivas desta forma como uma matriz no final ou se você deseja agrupar os totais por essas datas. Portanto, lembre-se principalmente das partes $unwind e $project usando os operadores de data.

--EDITAR--

Com agradecimentos à comunidade, conforme mostrado esta postagem existe isso não documentado comportamento de $substr , em que inteiros podem ser convertidos como strings.
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"} }}
])

E agora os days são cordas. Como observei antes, se a ordenação for importante para você, a melhor abordagem é projetar em um tipo de documento como foi feito e classificar nas teclas numéricas. Naturalmente, o $project que transforma a data pode ser enrolado no $group stage por brevidade, o que provavelmente é o que você deseja fazer ao trabalhar com todo o documento.