必须在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 值?
答案 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" }
}
}
},
[]
]
}
}
}
])
也可以使用$reduce
代替$filter
db.collection.aggregate([
{
$match: {
$expr: {
$not: {
$reduce: {
input: "$whiteList",
initialValue: false,
in: {
$or: [
{
$regexMatch: { input: "$script_url", regex: "$$this" }
},
"$$value"
]
}
}
}
}
}
}
])