如何通过查询子文档将数组用作过滤器

时间:2018-03-03 19:11:13

标签: mongodb mongodb-query aggregation-framework

我的mongodb集合上有以下文档结构:

{
"_id" : "5Ci9sLeBu2iPbWtR5",
"productId" : "010101111",
"description" : "PRODUCT EXAMPLE REF 1001",
"prices" : [ 
    {
        "priceId" : 10,
        "description" : "Promotions",
        "price" : 97.99
    },
    {
        "priceId" : 15,
        "description" : "Retail list",
        "price" : 105.65
    },
    {
        "priceId" : 20,
        "description" : "Standard list",
        "price" : 109.10
    }
]}

我想要的只是查询priceIds的特定数组,例如:[10,20],结果:

{
"_id" : "5Ci9sLeBu2iPbWtR5",
"productId" : "010101111",
"description" : "PRODUCT EXAMPLE REF 1001",
"prices" : [ 
    {
        "priceId" : 10,
        "description" : "Promotions",
        "price" : 97.99
    },
    {
        "priceId" : 20,
        "description" : "Standard list",
        "price" : 109.10
    }
]}

$ in 运算符与 $ filter 一起使用(完美的假想场景):

db.getCollection('products').aggregate([
{$match: { "productId":"010101111" }},
{$project: { 
    "prices": {
        $filter: {
            input: "$prices",
            as: "price",
            cond: { $in: ["$$price.priceId",[10, 20]] }
        }
    }
}}])

它不起作用,因为mongodb抱怨$ in operator("无效的运算符' $ in'"")。

当然,我可以通过 $ unwind 来实现这一点,但我会遇到性能问题,因为我需要再次进行分组。

我在问题中找到的最接近的答案是这两个:

  1. Retrieve only the queried element in an object array in MongoDB collection
  2. Filter array using the $in operator in the $project stage
  3. 但它们都没有关于在子文档中使用数组过滤器进行搜索。

1 个答案:

答案 0 :(得分:1)

$in运算符仅在MongoDB 3.4+的聚合管道中有效。但是,解决方法涉及使用集合运算符。使用 $setIsSubset 作为替代,如果第一个集合的所有元素都出现在第二个集合中,则返回true,包括第一个集合等于第二个集合时:

cond: { $setIsSubset: [["$$price.priceId"],[10, 20]] }