MongoDB-查询ObjectId嵌套数组

时间:2018-08-18 21:05:40

标签: node.js mongodb mongoose

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

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

“品牌”键引用了另一个名为品牌的集合,例如:

[
    {
        _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 });

有一种方法可以通过一个查询来做到这一点吗?

1 个答案:

答案 0 :(得分:2)

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

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

或在下一阶段仅将$lookup$filter一起使用,以过滤掉已弃用的品牌:

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