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

Posted

技术标签:

【中文标题】mongodb 聚合 - 匹配 $nin 数组正则表达式值【英文标题】:mongodb aggregate - match $nin array regex values 【发布时间】:2020-11-02 16:25:39 【问题描述】:

必须在 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_urlwhiteList 的正则表达式值匹配?

更新

我能够在我的聚合中达到这个阶段:


    "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 值?

【问题讨论】:

将值作为正则表达式传递,您将其作为字符串传递。 这是将值保存在数据库中的方式。这是一个投影。正则表达式值在数组中作为字符串。如果我能够将它们转换为聚合中的正则表达式值,则匹配将起作用。你知道怎么做吗? 您的问题显示了一个文档。你指的是哪个投影? @D.SM 此文档是聚合块的结果。我的意图是添加一个 $match 块来过滤掉白名单数组中存在的 script_url - 但与正则表达式值进行比较。目前还不能将白名单值保存为正则表达式值。 那么投影是什么? 【参考方案1】:

我知道您特别提到了 v3.4,但我找不到使用 v3.4 使其工作的解决方案。

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

仅适用于 4.2 或更高版本

诀窍是在whitelist 上使用$filter 使用$regexMatch(可从v4.2 获得),如果过滤后的数组为空,则意味着script_urlwhitelist 中的任何内容都不匹配

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

【讨论】:

谢谢@thammada.ts 但不幸的是我的系统是v3.4,我们目前不打算升级。它必须在 v3.4 上工作 @asafg 只是一点提示。从mongodb.com/support-policy可以看到2020年1月对v3.4的支持已经结束 从我在文档中可以找到的内容来看,我会说使用 v3.4 是不可能的。如果有某种方法可以将值转换为正则表达式(没有),您仍然需要$expr 才能在聚合中使用,这在 v3.6 中可用。另一种可能性是使用$where,它在您的所有文档上运行javascript,但它不支持聚合。 谢谢@thammada.ts。我最终制作了一份 whiteList - regexWhiteList 的副本,其中包含原始的正则表达式值。当我们迁移到 v4 时,我们将能够删除这些不必要的数据。感谢您的努力! @asafg 太棒了!我不知道我们可以在 MongoDB 中存储正则表达式

以上是关于mongodb 聚合 - 匹配 $nin 数组正则表达式值的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB:使用正则表达式聚合数组元素

Mongodb聚合数组大小大于匹配[重复]

Mongodb聚合数组大小大于匹配[重复]

Mongodb 查找与聚合匹配返回一个空数组

如何在 mongoDB 中使用 nin 和 regex

为啥在与数组中的字段匹配时,mongoDB聚合中的查找中的管道不起作用?