Dan*_*Dan 9 regex performance mongodb aggregation-framework
假设我有这些字段的集合:
{
"category" : "ONE",
"data": [
{
"regex": "/^[0-9]{2}$/",
"type" : "TYPE1"
},
{
"regex": "/^[a-z]{3}$/",
"type" : "TYPE2"
}
// etc
]
}
Run Code Online (Sandbox Code Playgroud)
所以我的输入是"abc"所以我想获得相应的类型(或最佳匹配,尽管最初我假设RegExes是独占的).有没有可能通过良好的性能实现这一目标?(这将排除迭代RegEx数组的每个项目)
请注意,如果可能,可以重新安排架构,因为该项目仍处于设计阶段.所以替代方案将受到欢迎.
每个类别可以有大约100 - 150个RegExes.我打算有大约300个类别.但我知道这些类型是相互排斥的.
一个类别的真实世界示例:
type1=^34[0-9]{4}$,
type2=^54[0-9]{4}$,
type3=^39[0-9]{4}$,
type4=^1[5-9]{2}$,
type5=^2[4-9]{2,3}$
Run Code Online (Sandbox Code Playgroud)
描述 RegEx ( Divide et Impera ) 将极大地有助于限制需要处理的文档数量。
这个方向的一些想法:
[:alpha:]、[:digit:]、[:alnum:]等)实现其中每一个都会增加插入的复杂性(代码和/或手动输入),并且还会增加在searchterm查询之前描述的一些开销。
在一个类别中拥有互斥的类型可以简化事情,但是类别之间呢?
300 个类别 @ 100-150 个正则表达式/类别 => 30k 到 45k 个正则表达式
...如果不是大多数的话,有些肯定是完全重复的。
在这种方法中,我将尝试最大限度地减少要以相反的方式存储/查询的文档总数,而不是您最初提出的“架构”。
注意:此演示中仅包含字符串长度以进行缩小,这对于手动输入来说可能很自然,因为它可以加强对正则表达式的视觉检查
考虑regexes用文档重写集合,如下所示:
{
"max_length": NumberLong(2),
"min_length": NumberLong(2),
"regex": "^[0-9][2]$",
"types": [
"ONE/TYPE1",
"NINE/TYPE6"
]
},
{
"max_length": NumberLong(4),
"min_length": NumberLong(3),
"regex": "^2[4-9][2,3]$",
"types": [
"ONE/TYPE5",
"TWO/TYPE2",
"SIX/TYPE8"
]
},
{
"max_length": NumberLong(6),
"min_length": NumberLong(6),
"regex": "^39[0-9][4]$",
"types": [
"ONE/TYPE3",
"SIX/TYPE2"
]
},
{
"max_length": NumberLong(3),
"min_length": NumberLong(3),
"regex": "^[a-z][3]$",
"types": [
"ONE/TYPE2"
]
}
Run Code Online (Sandbox Code Playgroud)
..每个唯一的正则表达式都是它自己的文档,具有它所属的类别(每个类别可扩展为多种类型)
演示聚合代码:
function () {
match=null;
query='abc';
db.regexes.aggregate(
{$match: {
max_length: {$gte: query.length},
min_length: {$lte: query.length},
types: /^ONE\//
}
},
{$project: {
regex: 1,
types: 1,
_id:0
}
}
).result.some(function(re){
if (query.match(new RegExp(re.regex))) return match=re.types;
});
return match;
}
Run Code Online (Sandbox Code Playgroud)
返回'abc'查询:
[
"ONE/TYPE2"
]
Run Code Online (Sandbox Code Playgroud)
这将仅针对这两个文档运行:
{
"regex": "^2[4-9][2,3]$",
"types": [
"ONE/TYPE5",
"TWO/TYPE2",
"SIX/TYPE8"
]
},
{
"regex": "^[a-z][3]$",
"types": [
"ONE/TYPE2"
]
}
Run Code Online (Sandbox Code Playgroud)
通过长度3和类别缩小ONE。
可以通过实现描述符进一步缩小范围POSIX(易于测试,searchterm但必须在数据库中输入 2 个正则表达式)
| 归档时间: |
|
| 查看次数: |
844 次 |
| 最近记录: |