说我有一个与这些领域的集合:

{
    "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)将大大有助于限制需要处理的文档数量。

在这个方向上的一些想法:

  • RegEx接受长度(固定,最小,最大)
  • POSIX样式字符类([:alpha:][:digit:][:alnum:]等)
  • 树状文档结构(umm)

  • 实现这些方法中的每一个都会增加插入的复杂性(代码和/或手动输入),并增加一些在查询之前描述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)

    10-08 14:32