mongo $filter 和子子数组中的多个条件

Fra*_*sco 5 mongodb mongodb-query aggregation-framework

我有这部分的收藏:

[{
  "_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"
    }]
}]
Run Code Online (Sandbox Code Playgroud)

这个查询:

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] }
                        ]
                    }
                }
            }
        }
    }
])
Run Code Online (Sandbox Code Playgroud)

结果是一个新的数组匹配,在本例中,

"match": [
      {
        "id": ObjectId("602b764ff4b4bf5b41662ec2"),
        "name": "debug",
        "sel": true
      }
    ]
Run Code Online (Sandbox Code Playgroud)

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

"id": ObjectId("602b764ff4b4bf5b41662ec2") and 
"id": ObjectId("602b764ff4b4bf5b41662ec4")
Run Code Online (Sandbox Code Playgroud)

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

tur*_*hal 3

我不确定在单一条件下是否可行$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",
              []
            ]
          }
        }
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

操场