I'm working on the following document

{
"_id" : 12,
"firstName" : "wer",
"People" : [ 
    {
        "uuid" : "123",
        "name" : "sugun",
        "person" : [ 
            {
                "uuid" : "add32",
                "name" : "ssss"
            }, 
            {
                "uuid" : "fdg456",
                "name" : "gfg"
            }
        ]
    }, 
    {
        "uuid" : "222",
        "name" : "kiran"
    }
]
} 

I want to get my output as following

{
"_id" : 456,
"People" : [ 
    {
        "uuid" : "123",
        "name" : "sugun",
        "person" : [ 
            {
                "uuid" : "add32",
                "name" : "ssss"
            }
        ]
    }
]
}

when iam using following command in mongo shell it give my required output

 db.people.aggregate([
    {$match: {_id: 12}}, 
    {$unwind: "$People"}, 
    {$unwind: "$People.person"}, 
    {$match: {"People.uuid": "123", "People.person.uuid" : "add32"}}
 ])

but when iam using same in my meteor app aggregate is not working...... so can i do the same using find or findOne methods............. or if there is any possibility to use aggregate function in my meteor app....

Solution 1

By using rawCollection you can pass in the same pipeline that you've been using in your mongo shell.

There is no need to install a third-party package to do this.

const stats = await MyCollection.rawCollection()
    .aggregate([
      {$match: {_id: 12}}, 
      {$unwind: "$People"}, 
      {$unwind: "$People.person"}, 
      {$match: {"People.uuid": "123", "People.person.uuid" : "add32"}}
    ])
    .toArray();

Solution 2

I used the meteorhacks:aggregate package. It works only on the server side.

meteor add meteorhacks:aggregate

MyCollection.aggregate({ 
  $match: { 
    propertyToQuery: 'valueForProperty' 
  }, { 
    $group: {
      _id: '$propertyToGroupBy',
      result: { $operation: '$propertyToPerformOperationOn' }
    }
});

https://github.com/meteorhacks/meteor-aggregate https://themeteorchef.com/snippets/aggregations-in-mongodb/

Solution 3

Here is what I tried manually and worked for me:

var rawUsers = Meteor.users.rawCollection();
var aggregateQuery = Meteor.wrapAsync(rawUsers.aggregate, rawUsers);
var pipeline = [
    {$match: {}},
    {$project: {username: 1, profile: 1}}
];
var result = aggregateQuery(pipeline);

return result;

Read more about Meteor.wrapAsync here

Solution 4

You need to add a package to expose the aggregate feature:

meteor add monbro:mongodb-mapreduce-aggregation

Then you can use the code like normal:

var MyCollection = new Mongo.Collection('metrics');
var pipeline = [
  {$group: {_id: null, resTime: {$sum: "$resTime"}}}
];

var result = MyCollection.aggregate(pipeline);

Just a couple of things to note, this works best on the server side. For docs to use it on the client side a fork of the package is needed, check the package's docs: https://atmospherejs.com/monbro/mongodb-mapreduce-aggregation