说我有一个与这些领域的集合:
{
"category" : "ONE",
"data": [
{
"regex": "/^[0-9]{2}$/",
"type" : "TYPE1"
},
{
"regex": "/^[a-z]{3}$/",
"type" : "TYPE2"
}
// etc
]
}
所以我的输入是“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}$
最佳答案
描述RegEx(Divide et Impera)将大大有助于限制需要处理的文档数量。
在这个方向上的一些想法:
[:alpha:]
,[:digit:]
,[:alnum:]
等)实现这些方法中的每一个都会增加插入的复杂性(代码和/或手动输入),并增加一些在查询之前描述
searchterm
的开销。在类别中具有互斥类型可以简化操作,但是类别之间又如何呢?
...如果不是大多数,某些肯定会是完全重复的。
在这种方法中,与您最初建议的“模式”相比,我将尝试以相反的方式使要存储/查询的文档总数最小化。
注意:此演示中仅包含字符串长度以进行缩小,对于手动输入而言,这很自然,因为它可以加强对RegEx的视觉检查
考虑使用文档撤销
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"
]
}
..每个唯一的RegEx作为其自己的文档,具有所属的类别(每个类别可扩展为多种类型)
演示汇总代码:
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;
}
返回
'abc'
查询:[
"ONE/TYPE2"
]
这将仅针对以下两个文档:
{
"regex": "^2[4-9][2,3]$",
"types": [
"ONE/TYPE5",
"TWO/TYPE2",
"SIX/TYPE8"
]
},
{
"regex": "^[a-z][3]$",
"types": [
"ONE/TYPE2"
]
}
通过长度
3
缩小并具有ONE
类别。可以通过实现
POSIX
描述符进一步缩小(易于针对searchterm
进行测试,但必须在数据库中输入2个RegExps)