153 votes

requête de groupe mongo comment conserver les champs

Tout le monde. Dans une requête de groupe mongo, le résultat ne montre que la ou les clés dans les arguments. Comment garder le premier document dans chaque groupe comme mysql query group. par exemple :

-------------------------------------------------------------------------
|  name  | age  |  sex  | province |   city   |   area   |   address     |
-------------------------------------------------------------------------
| ddl1st | 22   |  |  BeiJing |  BeiJing | ChaoYang | QingNianLu    |
| ddl1st | 24   |  |  BeiJing |  BeiJing | XuHui    | ZhaoJiaBangLu |
|  24k   | 220  | ...   |  ....    |  ...     | ...      | ...           |
-------------------------------------------------------------------------

db.users.group({key: { name: 1},reduce: function ( curr, result ) { result.count ++ },initial: {count : 0 } })

résultat :

[
{
    "name" : "ddl1st",
    "count" : 1
},
{
    "name" : "24k",
    "count" : 1
}
]

Comment obtenir les éléments suivants :

[
   {
   "name" : "ddl1st",
   "age" : 22,
   "sex" : "",
   "province" : "BeiJing",
   "city" : "BeiJing",
   "area" : "ChaoYang",
   "address" : "QingNianLu",
   "count" : 1
   },
   {
   "name" : "24k",
   "age" : 220,
   "sex" : "...",
   "province" : "...",
   "city" : "...",
   "area" : "...",
   "address" : "...",
   "count" : 1
}
]

313voto

nyde1319 Points 579

Si vous souhaitez conserver les informations sur les premières entrées correspondantes pour chaque groupe, vous pouvez essayer de les agréger comme suit :

    db.test.aggregate([{
      $group: {
         _id : '$name',
         name : { $first: '$name' },
         age : { $first: '$age' },
         sex : { $first: '$sex' },
         province : { $first: '$province' },
         city : { $first: '$city' },
         area : { $first: '$area' },
         address : { $first: '$address' },
         count : { $sum: 1 },
      }
    }]);

58voto

Pieter Points 616

[édité pour inclure les suggestions de commentaires]

Je suis venu ici pour chercher une réponse mais je n'étais pas satisfait de la réponse choisie (surtout compte tenu de son âge). J'ai trouvé cette réponse qui est une meilleure solution (adaptée) :

db.test.aggregate({
  $group: {
    _id: '$name',
   person: { "$first": "$$ROOT" },
   count: { $sum: 1 }
  },
  {
    "$replaceRoot": { "newRoot": { "$mergeObjects": ["$person", { count: "$count" }]} }
  }
}

30voto

陈学铄 Points 349

A propos, si vous voulez garder non seulement le premier document, vous pouvez utiliser $addToSet Par exemple :

db.test.aggregate({
  $group: {
    _id: '$name',
    name : { $addToSet: '$name' }
    age : { $addToSet: '$age' },
    count: { $sum: 1 }
  }
}

13voto

Deeksha Sharma Points 19

Vous pouvez essayer ceci

db.test.aggregate({
      { $group: 
            { _id: '$name',count: { $sum: 1 }, data: { $push: '$$ROOT' } } },
      {
        $project: {
          _id:0,
          data:1,
          count :1
        }
      }

}

12voto

Gary Wild Points 1

Juste une mise à jour rapide si quelqu'un rencontre le même problème avec des documents comportant de nombreux champs. On peut utiliser la possibilité de combiner le $replaceRoot et le stade du pipeline $mergeObjects opérateur de pipeline.

db.users.aggregate([
  {
    $group: {
      _id: '$name',
      user: { $first: '$$ROOT' },
      count: { $sum: 1 }
    },
  },
  {
    $replaceRoot: {
      newRoot: { $mergeObjects: [{ count: '$count' }, '$user'] }
    }
  }
])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X