Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to group in mongoDB and return all fields in result

I am using aggregate method in mongoDB to group but when I use $group it returns the only field which I used to group. I have tried $project but it is not working either. I also tried $first and it worked but the result data is now in different format.

The response format I need looks like:

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

and after adding $group in my query.response is like this, the value of _id changes. (and the $group is taking only _id, if i try any other keyword it throws an error of accumulator something. please explain this also.)

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

I have to remove the duplicates in name field, without changing any structure and fields. also I am using nodeJS with mongoose, so please provide the solution that works with it.

like image 234
Anukool Avatar asked Sep 29 '18 09:09

Anukool


People also ask

Can we use group by in MongoDB?

MongoDB group by is used to group data from the collection, we can achieve group by clause using aggregate function and group method in MongoDB. While using aggregate function with group by clause query operations is faster as normal query, basically aggregate function is used in multiple condition.

What is $$ root in MongoDB?

The $$ROOT variable contains the source documents for the group. If you'd like to just pass them through unmodified, you can do this by $pushing $$ROOT into the output from the group.

How do I display multiple fields in MongoDB?

In MongoDB, When you want to perform any operation on multiple fields then you have to use $group aggregation. You will more understand with help of examples. Example: In the example, I will show you how you can display some particular documents with multiple fields when we have a large dataset in the collection.

What is _ID in Group MongoDB?

The _id expression specifies the group key. If you specify an _id value of null, or any other constant value, the $group stage returns a single document that aggregates values across all of the input documents.


2 Answers

You can use below aggregation query.

$$ROOT to keep the whole document per each name followed by $replaceRoot to promote the document to the top.

db.col.aggregate([
  {"$group":{"_id":"$name","doc":{"$first":"$$ROOT"}}},
  {"$replaceRoot":{"newRoot":"$doc"}}
])
like image 72
s7vr Avatar answered Oct 17 '22 12:10

s7vr


user2683814's solution worked for me but in my case, I have a counter accumulator when we replace the newRoot object, the count field is missing in the final stage so I've used $mergeObjects operator to get my count field back.

db.collection.aggregate([
 {
  $group: {
    _id: '$product',
    detail: { $first: '$$ROOT' },
    count: {
      $sum: 1,
    },
  },
},
{
  $replaceRoot: {
    newRoot: { $mergeObjects: [{ count: '$count' }, '$detail'] },
  },
}])
like image 14
Sathish Kumar Avatar answered Oct 17 '22 13:10

Sathish Kumar