web-dev-qa-db-fra.com

comment grouper dans mongoDB et retourner tous les champs dans le résultat

J'utilise la méthode d'agrégation dans mongoDB pour regrouper mais quand j'utilise $group il retourne le seul champ que j'ai utilisé pour grouper. J'ai essayé $project mais ça ne marche pas non plus. J'ai aussi essayé $first et cela a fonctionné mais les données de résultat sont maintenant dans un format différent.

Le format de réponse dont j'ai besoin ressemble à:

{
    "_id" : ObjectId("5b814b2852d47e00514d6a09"),
    "tags" : [],
    "name" : "name here",
    "rating" : "123456789"
}

et après avoir ajouté $ group dans ma query.response est comme ceci, la valeur de _id change. (et le groupe $ ne prend que _id, si j'essaie un autre mot-clé, il génère une erreur d'accumulateur. Veuillez l'expliquer également.)

{
    "_id" :"name here" //the value of _id changed to the name field which i used in $group condition
}

Je dois supprimer les doublons dans le champ de nom, sans changer la structure et les champs. J'utilise également nodeJS avec mangouste, veuillez donc fournir la solution qui fonctionne avec.

9
Anukool

Vous pouvez utiliser la requête d'agrégation ci-dessous.

$$ROOT pour conserver l'intégralité du document pour chaque nom suivi de $replaceRoot pour promouvoir le document en haut.

db.col.aggregate([
  {"$group":{"_id":"$name","doc":{"$first":"$$ROOT"}}},
  {"$replaceRoot":{"newRoot":"$doc"}}
])
23
Sagar Veeram

Lorsque vous regroupez des données sur une base de données, cela signifie que vous souhaitez effectuer une opération cumulée sur le champ requis et l'autre champ qui ne sera pas inclus dans l'opération cumulée sera utilisé dans un groupe comme

 db.collection.aggregate([{
 $group: {
   _id: { field1: "", field1: "" },
   acc: { $sum: 1 }
 }}]

ici, dans _id, l'objet contiendra tous les autres champs que vous souhaitez conserver.

pour vos données, vous pouvez essayer ceci

db.collection.aggregate([{
    $group: {
        _id: "$name",
        rating: { $first: "$rating" },
        tags: { $first: "$tag" },
        docid: { $first: "$_id" }
    }
},
{
    $project: {
        _id: "$docid",
        name: "$_id",
        rating: 1,
        tags: 1
    }
}])
3
Adnan Ahmed Ansari

la solution de user2683814 a fonctionné pour moi, mais dans mon cas, j'ai un compteur d'accumulateurs lorsque nous remplaçons l'objet newRoot, le champ de compte est manquant dans la phase finale, donc j'ai utilisé $mergeObjects opérateur pour récupérer mon champ de comptage.

db.collection.aggregate([
 {
  $group: {
    _id: '$product',
    detail: { $first: '$$ROOT' },
    count: {
      $sum: 1,
    },
  },
},
{
  $replaceRoot: {
    newRoot: { $mergeObjects: [{ count: '$count' }, '$product'] },
  },
}])
1
Sathish Kumar

Vous pouvez utiliser cette requête

db.col.aggregate([
                        {"$group" : {"_id" : "$name","data" : {"$first" : "$$ROOT"}}},
                        {"$project" : {
                            "tags" : "$data.tags",
                            "name" : "$data.name",
                            "rating" : "$data.rating",
                            "_id" : "$data._id"
                            }
                        }])
0
Senthur Deva