首页 > 解决方案 > MongoDB - 查询 ObjectId 嵌套数组

问题描述

我在 MongoDB 上有一个名为 Product 的集合,其中包含一些文档,这是一个示例:

{
    _id: 'xxxxxx',
    name: 'cellphone',
    brands: [
        'aaaaaa',
        'bbbbbb'
    ]
}

'brands' 键引用了另一个名为 Brand 的集合,例如:

[
    {
        _id: 'aaaaaa',
        name: 'Apple',
        _deprecatedDate: null
    },
    {
        _id: 'bbbbbb',
        name: 'BlackBerry',
        _deprecatedDate: '2016-07-13T02:27:17.724Z'
    }
]

因此,使用产品 ID,我想获得所有未弃用的品牌。我发现这样做的唯一方法是使用以下代码:

let _product = await Product.findOne({ _id: 'xxxxxx' });
return Brand.find({ _id: { $in: _product.brands },  _deprecatedDate: null });

有没有办法用一个查询来做到这一点?

标签: node.jsmongodbmongoose

解决方案


您可以使用$lookup从多个集合中获取数据.aggregate()。您可以指定自定义(MongoDB 3.6):pipeline

Product.aggregate([
    {
        $lookup: {
            from: "Brand",
            let: { brands: "$brands" },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and: [
                             { $in: [ "$_id",  "$$brands" ] },
                             { $eq: [ "$_deprecatedDate", null ] }
                           ]
                        }
                    }
                }
            ],
            as: "brands"
        }
    }
])

或者只是在下一阶段使用 $filter 来过滤掉不推荐使用的$lookup品牌

Product.aggregate([
    {
        $lookup: {
            from: "Brand",
            localField: "brands",
            foreignField: "_id",
            as: "brands"
        }
    },
    {
        $addFields: {
            brands: {
                $filter: {
                    input: "$brands",
                    as: "brand",
                    cond: {
                        $eq: [ "$$brand._deprecatedDate", null ]
                    }
                }
            }
        }
    }
])

推荐阅读