MongoDB 聚合 - 数组字段上的 $regexMatch

MongoDB aggregation - $regexMatch on array field

我正在使用 Mongo 的 $regexMatch 运算符来查找至少部分字段与模式匹配的文档,这对根级字段非常有效。但是我如何将它与数组字段一起使用呢?如果至少有一个数组元素与模式匹配,我想 return 匹配。

例如,假设集合中有这两个文档:

{
  "_id": ObjectId("5ff6335c1570ba63ca5ac21e"),
  "requirements": [
    {
      "description": "Bachelor of Science required for this blah blah blah",
      "code": "ABC"
    },
    {
      "description": "Also much experience in JavaScript blah",
      "code": "XYZ"
    }
  ]
},

{
  "_id": ObjectId("5ff6335b1570ba63ca5abefb"),
  "requirements": [
    {
      "description": "Master of Arts WANTED NOW!",
      "code": "TTT"
    },
    {
      "description": "5+ experience required in C++",
      "code": "QQQ"
    }
  ]
}

还有类似这个管道的东西

db.Collection.aggregate([
  { $match:
     { $expr:
        { $regexMatch: { 
          input: '$requirements.description', 
          regex: /^.*?\bblah blah blah\b.*?$/im 
        } } 
     } 
  }
])

应该 return 只是 第一个文档,因为它在 requirements 中的第一个元素匹配 description 包含“blah blah blah” (“这个等等等等需要理学学士学位”)。

然而,这只会给我一个错误,提示“$regexMatch 需要 input 为字符串类型”。用 $requirements[0].description 替换它也不起作用。

那么有没有一种方法可以正则表达式匹配 Mongo 中的数组字段?

$regexMatch 只允许字符串输入 requirements 有数组需要迭代循环数组值,

  • $reduce 迭代 description 的循环,如果表达式匹配则检查条件 return 否则得分 return 初始值
db.collection.aggregate([
  {
    $addFields: {
      score: {
        $reduce: {
          input: "$requirements.description",
          initialValue: 0,
          in: {
            $cond: [
              {
                $eq: [
                  {
                    $regexMatch: {
                      input: "$$this",
                      regex: "blah blah blah"
                    }
                  },
                  true
                ]
              },
              50,
              "$$value"
            ]
          }
        }
      }
    }
  }
])

Playground


如果你想要过滤文档,只需在 $match 阶段尝试 $regex

db.collection.aggregate([
  {
    $match: {
      "requirements.description": {
        $regex: "blah blah blah"
      }
    }
  }
])

Playground