mongodb聚合-匹配$ nin数组正则表达式值

时间:2020-07-13 13:03:57

标签: regex mongodb mongoose aggregate

必须在mongo 3.4版中工作
你好 作为聚合相关标签的一部分,我想返回script_url数组中未包含的whiteList标签。
问题是,我想将script_url与数组值的 regex 比较。
我有这个预测:

{
    "script_url" : "www.analytics.com/path/file-7.js",
    "whiteList" : [ 
        null, 
        "www.analytics.com/path/*", 
        "www.analytics.com/path/.*", 
        "www.analytics.com/path/file-6.js", 
        "www.maps.com/*", 
        "www.maps.com/.*"
    ]
}

$matchscript_url与精确的whiteList值进行比较。因此,上面给出的文档在whiteList

中具有 www.analytics.com/path/. *时不应该通过
{
    "$match": {
        "script_url": {"$nin": ["$whiteList"]}
    }
}

我如何将script_url与正则表达式值whiteList匹配?

更新

我能够在汇总阶段达到这一阶段:

{
    "script_url" : "www.asaf-test.com/path/file-1.js",
    "whiteList" : [ 
        "http://sd.bla.com/bla/878/676.js", 
        "www.asaf-test.com/path/*"
    ],
    "whiteListRegex" : [ 
        "/http:\/\/sd\.bla\.com\/bla\/878\/676\.js/", 
        "/www\.asaf-test\.com\/path\/.*/"
    ]
}

但是$match并未像预期的那样过滤掉此script_url,因为它比较文字 strings 且未将数组值转换为 regex 价值观。 是否可以使用 v3.4 $map中的数组值转换为 Regex 值?

1 个答案:

答案 0 :(得分:3)

我知道您特别提到v3.4,但是我找不到解决方案以使其能够在v3.4上正常工作。

因此对于其他限制较少且能够使用v4.2的用户来说,这是一种解决方案。

仅适用于4.2或更高版本

技巧是使用$filter(可从v4.2获取)在whitelist上使用$regexMatch,如果过滤后的数组为空,则意味着script_url不会匹配whitelist

中的任何内容
db.collection.aggregate([
  {
    $match: {
      $expr: {
        $eq: [
          {
            $filter: {
              input: "$whiteList",
              cond: {
                $regexMatch: { input: "$script_url", regex: "$$this" }
              }
            }
          },
          []
        ]
      }
    }
  }
])

Mongo Playground

也可以使用$reduce代替$filter

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $not: {
          $reduce: {
            input: "$whiteList",
            initialValue: false,
            in: {
              $or: [
                {
                  $regexMatch: { input: "$script_url", regex: "$$this" }
                },
                "$$value"
              ]
            }
          }
        }
      }
    }
  }
])

Mongo Playground