首页 > 解决方案 > mongodb通过另一个具有ID的数组获取对象数组中的项目(聚合$ in)

问题描述

我的 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
        }
    ]
}
]

我只需要获取shopItems中的itemId在另一个数组中的文档

我是从产品集合的另一个查询中得到的

这是具有 ids ['2', '3'] <- 这只是例如,有 mongodb 对象 Ids 的数组

我的聚合查询效果很好:

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
                }
            }
        ])

所以作为输出我需要有这个数据:

{
    "_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
        }
    ]
}

标签: javascriptnode.jsmongodbmongoose

解决方案


如果我理解正确,您只需要$filter在这样的$project阶段使用:

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

这里的例子


推荐阅读