【问题标题】:MongoDB aggregation - $regexMatch on array fieldMongoDB 聚合 - 数组字段上的 $regexMatch
【发布时间】:2021-01-13 03:20:33
【问题描述】:

我正在使用 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 
        } } 
     } 
  }
])

应该返回只是requirements 中的第一个元素匹配包含“blah blah blah”的description 以来的第一个文档 (“这个废话需要科学学士学位”)。

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

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

【问题讨论】:

  • 您的期望是什么?它应该返回一个匹配的文档?它应该返回分数吗?你能显示预期的结果吗,
  • 为了清楚起见,我更新了示例——但期望它返回任何与模式匹配的文档(在这种情况下,将“blah blah blah”作为至少一个描述的一部分他们的要求)
  • 只需使用 $regex 运算符,请参阅playground
  • 哦,哇,这太简单了——有没有办法用 $addFields 而不是 $match 来做同样的事情来添加一个分数字段?

标签: regex mongodb aggregation-framework nosql-aggregation


【解决方案1】:

$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


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

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

Playground

【讨论】:

  • 当正则表达式就在那儿时,努力使 regexMatch 对对象数组起作用:') 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
相关资源
最近更新 更多