繁体   English   中英

在MongoDB Collection中查找与RegEx数组匹配

[英]Find match over Array of RegEx in MongoDB Collection

假设我有这些字段的集合:

{
    "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一些开销。

在一个类别中具有互斥类型简化了事物,但类别之间又如何呢?

300个类别@ 100-150 RegExps / category => 30k到45k RegExps

......如果不是大多数,有些肯定会完全重复。

在这种方法中,我将尝试以相反的方式最小化要存储/查询的文档总数与最初提出的“模式”。
注意:此演示中仅包含字符串长度以缩小,这可能会自然而然地用于手动输入,因为它可以加强对RegEx的视觉检查

考虑使用Documents重写正则regexes Collection,如下所示:

{
   "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)

广度优先搜索。 如果您的输入以字母开头,您可以丢弃类型1,如果它还包含一个数字,您可以丢弃独占(仅限数字或仅字母)类别,如果它还包含符号,则只保留少数包含所有类型的类型三。 然后按照上述建议了解其余类别。 从某种意义上说,为输入类型设置案例,并为选定数量的“正则表达式类型”设置用例以向下搜索到正确的类型。

或者,您可以根据输入创建正则表达式模型,并将其与作为字符串存在的正则表达式模型列表进行比较以获取类型。 这样你只需要花费资源分析输入来为它构建正则表达式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM