Mongodb 2 Collection Query Aggregation

I have 2 collections.One is resources other is items

resources:

{
    "_id" : "fGR4ECcw5p2HFgxd3",
    "ownerId" : "J8MpsWChPQdET6jwQ",
    "createdAt" : ISODate("2018-07-04T07:25:28.418Z"),
    "inventory" : [ 
        {
            "_id" : ObjectId("5b537ef5895adfeae037e0a4"),
            "quantity" : 10
        },
        {
            "_id" : ObjectId("5b537d9c895adfeae037dbd2"),
            "quantity" : 5
        }
    ]
}

There are 2 documents in items Collection:

{
    "_id" : ObjectId("5b537d9c895adfeae037dbd2"),
    "name" : "Item1",
    "useable" : true,
    "img" : ""
}

{
    "_id" : ObjectId("5b537ef5895adfeae037e0a4"),
    "name" : "Item2",
    "useable" : false,
    "img" : ""
}

As you see there are ids of items in inventory array.

What i am trying to do is how do i write a correct query to get an inventory array with each items information(coming from items collection)

Example:

    "inventory" : [ 
            {
                "_id" : ObjectId("5b537ef5895adfeae037e0a4"),
                "name":"Item2",
                "useable":false,
                "img":"",
                "quantity" : 10
            },
            {
                "_id" : ObjectId("5b537d9c895adfeae037dbd2"),
                "name":"Item1",
                "useable":true,
                "img":"",
                "quantity" : 5
            }
]

I am using meteor hacks aggregation package:
This is server side method:

'getInventory':function(userid){
    return Resources.aggregate([
      { "$match": { "ownerId": userid } },
      { "$unwind": "$inventory" },
      { "$lookup": {
        "from": Items.name,
        "let": { "inventoryId": "$inventory._id", "quantity": "$quantity" },
        "pipeline": [
          { "$match": { "$expr": { "$eq": [ "$_id", "$$inventoryId" ] } } },
          { "$addFields": { "quantity": "$$quantity" } }
        ],
        "as": "inventory"
      }},
      { "$unwind": "$inventory" },
      { "$group": {
        "_id": "$_id",
        "ownerId": { "$first": "$ownerId" },
        "createdAt": { "$first": "$createdAt" },
        "inventory": { "$push": "$inventory" }
      }}
    ])
  }

This is the error i get : 
W20180721-23:18:22.253(3)? (STDERR) (node:10800) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
W20180721-23:18:22.254(3)? (STDERR)     at Array.some (<anonymous>)
W20180721-23:18:22.254(3)? (STDERR)     at Object.matchObject (packages/ejson/ejson.js:180:31)
W20180721-23:18:22.254(3)? (STDERR)     at toJSONValueHelper (packages/ejson/ejson.js:239:19)
W20180721-23:18:22.254(3)? (STDERR)     at Object.EJSON.toJSONValue.item [as toJSONValue] (packages/ejson/ejson.js:292:19)
W20180721-23:18:22.255(3)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:188:29)
W20180721-23:18:22.255(3)? (STDERR)     at Array.forEach (<anonymous>)
W20180721-23:18:22.255(3)? (STDERR)     at Object.toJSONValue (packages/ejson/ejson.js:187:24)
W20180721-23:18:22.256(3)? (STDERR)     at toJSONValueHelper (packages/ejson/ejson.js:240:24)
W20180721-23:18:22.256(3)? (STDERR)     at Object.EJSON.toJSONValue.item [as toJSONValue] (packages/ejson/ejson.js:292:19)
W20180721-23:18:22.257(3)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:188:29)
W20180721-23:18:22.257(3)? (STDERR)     at Array.forEach (<anonymous>)
W20180721-23:18:22.258(3)? (STDERR)     at Object.toJSONValue (packages/ejson/ejson.js:187:24)
W20180721-23:18:22.258(3)? (STDERR)     at toJSONValueHelper (packages/ejson/ejson.js:240:24)
W20180721-23:18:22.259(3)? (STDERR)     at Object.EJSON.toJSONValue.item [as toJSONValue] (packages/ejson/ejson.js:292:19)
W20180721-23:18:22.259(3)? (STDERR)     at Object.keys.forEach.key (packages/ejson/ejson.js:188:29)
W20180721-23:18:22.259(3)? (STDERR)     at Array.forEach (<anonymous>)
W20180721-23:18:22.260(3)? (STDERR) (node:10800) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
W20180721-23:18:22.261(3)? (STDERR) (node:10800) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.```

Don’t use meteor hacks … the new version of mongo driver now returns a promise for aggregation. Here is a copy-paste from our code, adjust for your case.

Promise.await(Resources.rawCollection().aggregate(pipeline, {allowDiskUse:true}).toArray());

2 Likes