首页 > 解决方案 > mongo $filter 和子子数组中的多个条件

问题描述

我有这部分收藏:

[{
  "_id": ObjectId("604f3ae3194f2135b0ade569"),
  "parameters": [
    {
      "_id": ObjectId("602b7455f4b4bf5b41662ec1"),
      "name": "Purpose",
      "options": [
        {
          "id": ObjectId("602b764ff4b4bf5b41662ec2"),
          "name": "debug",
          "sel": true
        },
        {
          "id": ObjectId("602b767df4b4bf5b41662ec3"),
          "name": "performance",
          "sel": false
        },
        {
          "id": ObjectId("602b764ff4b4bf5b41662ec4"),
          "name": "security",
          "sel": true
        },
        {
          "id": ObjectId("602b767df4b4bf5b41662ec5"),
          "name": "Not Applicable",
          "sel": false
        }
      ],
      "type": "multiple"
    }]
}]

这个查询:

db.testCollection.aggregate([
    { $unwind: "$parameters" },
    {
        $match: {
            "parameters._id": ObjectId("602b7455f4b4bf5b41662ec1"),
        }
    },
    {
        $addFields: {
            match: {
                $filter: {
                    input: "$parameters.options",
                    as: "option",
                    cond: {
                        $and: [
                           { $eq: ["$$option.id", ObjectId('602b764ff4b4bf5b41662ec2')] },
                           { $eq: ["$$option.sel", true] }
                        ]
                    }
                }
            }
        }
    }
])

结果是一个新的数组匹配,在这种情况下,

"match": [
      {
        "id": ObjectId("602b764ff4b4bf5b41662ec2"),
        "name": "debug",
        "sel": true
      }
    ]

我如何匹配,对于集合,例如匹配

"id": ObjectId("602b764ff4b4bf5b41662ec2") and 
"id": ObjectId("602b764ff4b4bf5b41662ec4")

并有一个结果数组或两个结果或为空?

标签: mongodbmongodb-queryaggregation-framework

解决方案


我不确定在单一条件下是否可能$filter,但你可以尝试$let

  • $let声明一个名为的变量filtered并存储您的过滤结果
  • $in检查条件,如果过滤后的元素大小为 2,则返回过滤后的结果,否则返回空白数组
  • 您必须将与过滤器中的 id 数匹配的数字置于$eq条件中
  {
    $addFields: {
      match: {
        $let: {
          vars: {
            filtered: {
              $filter: {
                input: "$parameters.options",
                as: "option",
                cond: {
                  $and: [
                    {
                      $in: [
                        "$$option.id",
                        [ObjectId("602b764ff4b4bf5b41662ec2"), ObjectId("602b767df4b4bf5b41662ec3")]
                      ]
                    },
                    { $eq: ["$$option.sel", true] }
                  ]
                }
              }
            }
          },
          in: {
            $cond: [
              { $eq: [{ $size: "$$filtered" }, 2] },
              "$$filtered",
              []
            ]
          }
        }
      }
    }
  }

操场


推荐阅读