MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Analogique pour le groupe concat en sql

Selon les commentaires jusqu'à présent, il n'est pas clair ce que vous regroupez ou ce que vous voulez comme résultat final, à part pour dire que vous voulez que vos dates soient concaténées en quelque chose comme "juste le jour" sans heures ni minutes ensemble. Vraisemblablement, vous voulez ces jours distincts dans un but précis.

Il existe différents Opérateurs de date dans le pipeline, vous pouvez utiliser des dates, et le est le $concat opérateur également. Malheureusement, tous les opérateurs de date produisent un entier comme résultat, et pour le type de chaîne de date que vous voulez, $concat ne fonctionnera qu'avec des chaînes. L'autre problème étant que vous ne pouvez pas caster l'entier dans un type de chaîne dans l'agrégation.

Mais vous pouvez utilisez des sous-documents, ici nous ne travaillerons qu'avec la date :

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"} }}
])

Donc, ce n'est pas une chaîne, mais elle peut facilement être post-traitée en une seule, mais surtout elle est regroupée et triable.

Les principes restent les mêmes si vous souhaitez des dates uniques de cette façon sous forme de tableau à la fin ou si vous souhaitez regrouper les totaux par ces dates. Gardez donc à l'esprit les parties $unwind et $project utilisant les opérateurs de date.

--MODIFIER--

Avec nos remerciements à la communauté comme indiqué dans cet article il y a ce sans papiers comportement de $substr , dans lequel les entiers peuvent être convertis en chaînes.

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"} }}
])

Et maintenant les days sont des chaînes. Comme je l'ai déjà noté, si l'ordre est important pour vous, la meilleure approche consiste à projeter dans un type de document comme cela a été fait et à trier sur les touches numériques. Naturellement, le $project qui transforme la date peut être enroulé dans le $group stage pour plus de concision, ce qui est probablement ce que vous voulez faire lorsque vous travaillez avec l'ensemble du document.