0

I'd like to know a query in which I could get a specific sub-doc using it's ObjectId- or even it's "store" name if it's easier- using the aggregation method. I'm pretty sure I can use $project but I'm not sure how to apply that to an ObjectId.

I can use the find method but I need it to be in an aggregation method so mongo will return to me the item's names and not it's ObjectId.

db.stores.aggregate([
  {$unwind: '$inventory'},
  {$lookup: {
    from: 'items',
    localField: 'inventory.item',
    foreignField: '_id',
    as: 'itemsData'
   }},
  {$unwind: '$itemsData'},
  {$group:{
    _id: "$_id",
    inventory: { $push: "$inventory" },
    itemsData: { $push: "$itemsData" }
  }}
]).pretty()

I have five stores in my store collection. This query returns all five documents like the code below this, just five times. But I want to specify stores to be returned using it's ObjectId.


{
        "_id" : ObjectId("5cc0d6ad1ea502abb28b52cc"),
        "inventory" : [
                {
                        "item" : ObjectId("5cbe70bd1ea502abb28b52a4"),
                        "amount" : 9
                },
                {
                        "item" : ObjectId("5cbe70bd1ea502abb28b52a1"),
                        "amount" : 5
                },
                {
                        "item" : ObjectId("5cbe70bd1ea502abb28b52a7"),
                        "amount" : 2
                },
                {
                        "item" : ObjectId("5cbe70bd1ea502abb28b529e"),
                        "amount" : 5
                }
        ],
        "itemsData" : [
                {
                        "_id" : ObjectId("5cbe70bd1ea502abb28b52a4"),
                        "item" : "beans",
                        "price" : NumberDecimal("53,75")
                },
                {
                        "_id" : ObjectId("5cbe70bd1ea502abb28b52a1"),
                        "item" : "bananas",
                        "price" : NumberDecimal("5.00")
                },
                {
                        "_id" : ObjectId("5cbe70bd1ea502abb28b52a7"),
                        "item" : "watermelon",
                        "price" : NumberDecimal("3.50")
                },
                {
                        "_id" : ObjectId("5cbe70bd1ea502abb28b529e"),
                        "item" : "broccoli",
                        "price" : NumberDecimal("5.50")
                }
        ]

}

I want the query to return back the code just like the one above, with only one store and not five. I'm not sure how to use $project if it's suitable for this task.

aeon
  • 3
  • 1

1 Answers1

0

As you said only one store data to be return, so you can use $limit :

db.stores.aggregate([
   {$unwind: '$inventory'},
   {$lookup: {
      from: 'items',
      localField: 'inventory.item',
      foreignField: '_id',
      as: 'itemsData'
   }},
   {$unwind: '$itemsData'},
   {$group:{
      _id: "$_id",
      inventory: { $push: "$inventory" },
      itemsData: { $push: "$itemsData" }
   }},
   { $limit : 1}
  ]).pretty()

now, if you want to return specific store data to be return use $match Query :

db.stores.aggregate([
   { $match : { "_id" : ObjectId("5cc0d6ad1ea502abb28b52cc") }},
   {$unwind: '$inventory'},
   {$lookup: {
      from: 'items',
      localField: 'inventory.item',
      foreignField: '_id',
      as: 'itemsData'
   }},
   {$unwind: '$itemsData'},
   {$group:{
      _id: "$_id",
      inventory: { $push: "$inventory" },
      itemsData: { $push: "$itemsData" }
   }}
  ]).pretty()

Hope, this was helpful.

the_mahasagar
  • 1,201
  • 2
  • 16
  • 24