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

问题描述

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

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

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

应该返回 just一个文档,因为它在 requirements 中的第一个元素匹配 description 包含“blah blah blah” (“这个废话需要理科学士学位”)。

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

那么有没有办法在 Mongo 中正则表达式匹配数组字段?

解决方法

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

  • $reduce 迭代 description 的循环,如果表达式匹配则检查条件然后返回分数,否则返回初始值
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


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

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

Playground