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

5

我有这样一组集合:

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

是否可以得到一个包含两个结果或为空的结果数组?


尝试使用$in运算符代替$eq,{ $in: ["$$option.id", [ObjectId("602b764ff4b4bf5b41662ec2"), ObjectId("602b764ff4b4bf5b41662ec4")]] } - turivishal
嗨@turivishal,我已经在这里完成了(https://mongoplayground.net/p/Bw4Z8WWzKZy)。它可以工作,但是如果我选择一个错误的id(例如ObjectId(“602b767df4b4bf5b41662ec3”)),则新数组中的结果仅具有第一个匹配项。我期望它没有匹配项。 - Francesco
1个回答

3

我不确定在$filter中是否可能使用单个条件,但您可以尝试使用$let

  • 使用$let声明一个名为filtered的变量,并存储您筛选的结果
  • 使用$in检查条件,如果筛选的元素大小为2,则返回筛选结果,否则返回空数组
  • 您必须在$eq条件中放置与过滤器中匹配id数相同的数字
  {
    $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",
              []
            ]
          }
        }
      }
    }
  }

Playground


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接