mongodb get items in array of objects by another array with ID's (aggregation $in)

Viewed 82

I have stores collection in my mongodb

[
{
    "_id" : ObjectId("6043adb043707c034d5363b7"),
    "shopId" : "shopid1",
    "appId" : "777",
    "shopItems" : [
        {
            "itemId" : 1, <-- mongodbId
            // ..another fields
        },
        {
            "itemId" : 2 <-- mongodbId
            // ..another fields
        }
    ]
}
{
    "_id" : ObjectId("6043adb043707c034d5363b7"),
    "shopId" : "shopId2",
    "appId" : "777",
    "shopItems" : [
        {
            "itemId" : "itemId" : 1, <-- mongodbId
            // ..another fields
        },
        {
            "itemId" : "itemId" : 3, <-- mongodbId
            // ..another fields
        }
    ]
}
]

I need to get only documents where itemId in shopItems is in another array

I'm getting that from another query from products collection

this is array with ids ['2', '3'] <- this is just for example, there is mongodb object Ids

my query with aggregation works good:

const stores  = await Store.aggregate([
            { $match: query },
            { $unwind: "$shopItems" },
            {
                $lookup: {
                    from: "products",
                    localField: "shopItems.itemId",
                    foreignField: "_id",
                    as: "itemId"
                }
            },
            {
                $lookup: {
                    from: "colors",
                    localField: "shopItems.itemColor",
                    foreignField: "_id",
                    as: "itemColor"
                }
            },
            {
                $lookup: {
                    from: "sizes",
                    localField: "shopItems.itemSize",
                    foreignField: "_id",
                    as: "itemSize"
                }
            },
            {
                $lookup: {
                    from: 'shops',
                    localField: 'shopId',
                    foreignField: '_id',
                    as: 'shop'
                }
            },
            {$unwind: { path: '$shop', preserveNullAndEmptyArrays: true}},
            {
                $addFields: {
                    "shopItems.itemColor": { $arrayElemAt: ["$itemColor.colorName", 0] },
                    "shopItems.itemSize": { $arrayElemAt: ["$itemSize.sizeName", 0] },
                    "shopItems.itemName": { $arrayElemAt: ["$itemId.productName", 0] },
                    "shopItems.productArticle": { $arrayElemAt: ['$itemId.article', 0] },
                    "shopItems.productBarcode": { $arrayElemAt: ['$itemId.barCode', 0] },
                    "shopItems.shopName": "$shop.shopName",
                    "shopItems.shopId": "$shop._id",
                    "shopName": '$shop.shopName',
                }
            },
            {
                $group: {
                    _id: "$_id",
                    shopId: {$first: '$shop._id'},
                    shopItems: { $push: "$shopItems" },
                    shopName: { $first: '$shop.shopName' }
                }
            },
            {
                $project: {
                   shopId: 1,
                   shopName: 1,
                   shopItems: 1
                }
            }
        ])

so as output I need to have this data:

{
    "_id" : ObjectId("6043adb043707c034d5363b7"),
    "shopId" : "shopid1",
    "appId" : "777",
    "shopItems" : [
        {
            **"itemId" : 2** <-- mongodbId
            // ..another fields
        }
    ]
}
{
    "_id" : ObjectId("6043adb043707c034d5363b7"),
    "shopId" : "shopId2",
    "appId" : "777",
    "shopItems" : [
        {
            **"itemId" : 3**, <-- mongodbId
            // ..another fields
        }
    ]
}
1 Answers

If I've understood correctly you only need to use $filter in a $project stage like this:

{
  $project: {
    _id: 1,
    shopId: 1,
    appId: 1,
    shopItems: {
      $filter: {
        input: "$shopItems",
        as: "items",
        cond: {
          $in: [
            "$$items.itemId",
            yourDesiredArray
          ]
        }
      }
    }
  }
}

Example here

Related