【问题标题】:Indexing regular expressions (preferable in Lucene)索引正则表达式(最好在 Lucene 中)
【发布时间】:2012-02-16 22:54:54
【问题描述】:

有谁知道索引正则表达式的方法,这样我就可以运行非正则表达式查询,匹配其中包含正则表达式字段的文档?最好使用 Lucene 或其他进程内 Java 库。

背景

我在一个项目中工作,我们希望对大量用户交易进行分类。我们现在有工具可以做到这一点,但我们需要优化。

目前我正在探索 lucene 来替换一个内存排序树,该树是在父子关系中使用 HashMap、ConcurrentSkipListSets 实现的。

a  -> category cat1
   1  -> category cat2 

b  -> category cat4 
   \w*  
      6 -> category cat5 

所以字符串 'a 1''a 1 zx y' 将匹配 'cat2', 'a' 将匹配 'cat1',而 'bxy 6' 将匹配 'cat5'。所有规则的末尾都有一个隐含的 '.*',如果没有正则表达式匹配就可以进行匹配,那么它是首选的。这些规则是根据属性列表构建的:

a        = cat1
a 1      = cat2
b        = cat4
b \w* 6  = cat5

我们现在正在推送 50k 条规则(并且还在增加),虽然这个过程在查找时非常快,但它使用了太多的 RAM,需要一些时间来构建,并且没有我们需要的那么灵活。

我已经尝试使用 Lucene 来索引这些规则,但是我遇到了麻烦,因为正则表达式匹配了很多常用词(在我们的域中),并且为这些构建停用词并不容易,因为它们也经常变化.

所以重申一下 - 我需要一种方法来搜索正则表达式被索引的文档,而查询根本不知道正则表达式。

有人吗?

-- 奥尔夫

【问题讨论】:

  • 我的例子中的字母和数字当然不代表现实世界的价值。
  • 为什么不直接转义查询中的特殊字符? lucene.apache.org/java/3_5_0/queryparsersyntax.html#Escaping特殊字符
  • 当我输入查询如上所说的 'bxy 6' 时,我不知道在查询时 'x y' 会匹配规则 'b \w 6' 的正则表达式部分。我希望匹配尽可能类似于查询字符串,但在索引中使用正则表达式(以及最后的隐式 '.*' )。

标签: java regex search lucene indexing


【解决方案1】:

Lucene 无法帮助您解决问题,如果您有 n 个正则表达式并想找到一个与您的输入匹配的表达式,那么没有比针对您的输入运行每个正则表达式更好的方法了。实际上有一个方法,就是将你所有的正则表达式合并到一个有限状态机中,但这就是你目前正在做的事情。

但是,令我惊讶的是,您的进程使用了​​太多 RAM,而规则只有 50k。你有多少内存?如果您同意分享您的实施细节,我相信还有改进的余地。

关于构建时间,您的应用程序是如何工作的?也许可以将数据结构的编译版本存储在磁盘上以缩短启动时间,然后仅通过增量更新对其进行修改。

【讨论】:

  • 我已经凝视着得出同样的结论。我开始考虑创建自己的 KeywordAnalyzer/Tokenizer 版本,但我不确定是否可行。我有一些 Lucene 经验,但没有内部结构。我们将优化我们现在拥有的结构,并支持通过更新来修补结构,并使用数组而不是 SortedSets/Maps。我想这可能会增加构建时间,但会减少内存占用。一个挑战是正确地标记正则表达式 - 现在我们只支持 \w* 和 \d*
  • 我们在 RAM 上有点受限 - 我们在更改时重建整个结构,因此在重建期间我们消耗了两倍的大小。我猜这个结构本身使用了大约 40-50 MB。如果有多少我不知道,但我担心这个结构何时拥有 2-300k 的规则。它们是通过 GUI 添加的,而不是由程序员添加的。树结构首先按字母顺序分布在规则上的第一个字母(散列图)上,然后分布在使用 ConcurrentSkipListSet 的本土标准树实现上(不知道为什么 - 我们在创建时重建整个树)。
猜你喜欢
  • 2022-08-18
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
  • 2014-08-11
相关资源
最近更新 更多