首页 > 解决方案 > MongoDB:是否有可能将包含正则表达式的字段与聚合管道中 $match 阶段的字符串进行匹配?

问题描述

我目前正在尝试通过使用聚合管道来优化一些查询。现在我想要一个 $match 阶段来过滤掉大部分集合文档,以加快后续阶段的速度。我面临的问题是集合中的文档确实包含表示正则表达式的字段。我现在想根据这些正则表达式匹配字符串(最好在第一个 $match 阶段)。

这就是我当前的解决方案的外观。但就可读性和可能的​​性能而言,我对此并不满意。

[
    {$match: {
    name: "docName"
        }
    },
    {$addFields: {
    fieldAMatches: {$regexMatch: {input: "ABC", regex: '$fieldA'
                }
            }
        }
    },
    {$match: {
    fieldAMatches: true
        }
    }
]

示例数据集如下所示:

[
    {
        "_id": 1,
        "name": "docName",
        "fieldA": ".*"
    },
    {
        "_id": 2,
        "name": "docName",
        "fieldA": "AB.*"
    },
    {
        "_id": 3,
        "name": "docName",
        "fieldA": "AB.+"
    },
    {
        "_id": 4,
        "name": "docName",
        "fieldA": "BAC"
    }
]

结果包含以下文件:

[
    {
        "_id": 1,
        "name": "docName",
        "fieldA": ".*"
    },
    {
        "_id": 2,
        "name": "docName",
        "fieldA": "AB.*"
    },
    {
        "_id": 3,
        "name": "docName",
        "fieldA": "AB.+"
    },
]

标签: regexmongodb

解决方案


您可以使用$expr来实现这一点,来自文档:

$match 接受一个指定查询条件的文档。查询语法与读操作查询语法相同;即 $match 不接受原始聚合表达式。相反,使用 $expr 查询表达式在 $match 中包含聚合表达式。

通过使用$expr,我们可以在 stage 中包含聚合表达式(在我们的例子$regexMatch中),$match如下所示:

db.collection.aggregate([
  {
    $match: {
      name: "docName",
      $expr: {
        $regexMatch: {
          input: "ABC",
          regex: "$fieldA"
        }
      }
    }
  }
])

蒙戈游乐场


推荐阅读