使用Lucene进行Regex反向搜索



假设我存储的Lucene文档有一个代表正则表达式的regex存储字段。

doc.add(new StringField("regex", "d{3}[A-G]d{2}[A-G]d{2}", Store.YES));

我的搜索输入类似于123D56G89

有没有一种方法可以在我的TermQuery中进行反向匹配,并获取与给定输入匹配的所有文档?

MariaDB来自RDBMS背景,具有REGEXP功能。

如果您想利用搜索索引功能在次线性时间内搜索许多文档,那么,根据您的问题中提供的信息,没有办法。您必须检查索引中的每个文档,并对每个文档存储的表达式执行操作。

正则表达式本质上是一种程序类型通常,在无法推理表达式中编码的特定概念的情况下,评估它需要了解完整的表达式,并且引擎必须实际运行它。这意味着通常无法将字段汇总或分类到搜索索引中以加快查找速度。如果要根据N个正则表达式检查字符串,则必须逐一检查这N个正则公式并进行检查。在这一点上,搜索索引并没有为存储、获取或管理它们提供任何好处。

如果你对";"慢";搜索,并且您已经下定决心以这种方式存储任意表达式,那么从技术上讲,您可以实现一种新类型的查询,将字段视为正则表达式,并根据输入运行它。我不认为这是搜索索引的正常使用,但这种逻辑在技术上与任何其他类型的评估一样可行。

但是,也许您试图解决错误的问题。可能有一种更好的方法来表示您当前正试图存储为正则表达式的概念。如果你能设计一个更具体的";语言;或者结构,然后理论上,你可以创建一个分析器,将数据转换为可索引的字段&可优化。

示例:也许您只想使用正则表达式根据前缀中的数字数量,然后是字母数量来匹配某些ID代码(如1200ABC000121G021(。在这种情况下,与其对正则表达式进行索引,不如对这两个数字进行索引:前缀中的数字计数和字母计数。因此,如果搜索字符串是DG56,我可能会搜索与numberPrefixWidth:0 letterPrefixWidth:2之类的查询匹配的文档。或者对于搜索字符串789FGH4,我的查询将是numberPrefixWidth:3 letterPrefixWidth:3

因为我们已经简化了文档中实际表示的概念,所以不需要查看每个文档(基本上运行一个存储程序(来找到匹配的文档。我们可以使用Lucene来进行它快速的搜索。

注意:这个答案也适用于您的RDBMS示例。如果你想在MariaDB中做一些事情,比如WHERE someSearch REGEXP theRegexpColumn,引擎必须运行每一行并对其进行评估。在这样的设计中,没有任何基于索引的优化潜力。不同的是,Lucene更具特殊用途,并且没有像SQL那样广泛的语言来轻松运行这样的查询,而无需自己做一些工作。

最新更新