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/.*"
]
此$match
将script_url
与精确的whiteList
值进行比较。因此,上面给出的文档不应该通过,因为它在whiteList
"$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 值?
【问题讨论】:
将值作为正则表达式传递,您将其作为字符串传递。 这是将值保存在数据库中的方式。这是一个投影。正则表达式值在数组中作为字符串。如果我能够将它们转换为聚合中的正则表达式值,则匹配将起作用。你知道怎么做吗? 您的问题显示了一个文档。你指的是哪个投影? @D.SM 此文档是聚合块的结果。我的意图是添加一个 $match 块来过滤掉白名单数组中存在的 script_url - 但与正则表达式值进行比较。目前还不能将白名单值保存为正则表达式值。 那么投影是什么? 【参考方案1】:我知道您特别提到了 v3.4,但我找不到使用 v3.4 使其工作的解决方案。
因此,对于其他限制较少且能够使用 v4.2 的人来说,这是一种解决方案。
仅适用于 4.2 或更高版本
诀窍是在whitelist
上使用$filter
使用$regexMatch
(可从v4.2 获得),如果过滤后的数组为空,则意味着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
【讨论】:
谢谢@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 数组正则表达式值的主要内容,如果未能解决你的问题,请参考以下文章