当遇到模糊查询时,Lucene 在 OrientDB 上运行

Lucene acting up on OrientDB when confronted with fuzzy queries

我已经使用 Lucene 的关键字分析器在 OrientDB 上索引了一个 属性:

CREATE INDEX Snippet.ssdeep ON Snippet (ssdeep) FULLTEXT ENGINE LUCENE METADATA {"analyzer":"org.apache.lucene.analysis.core.KeywordAnalyzer"}

该文件包含我已为测试编制索引的 simhashes。

现在,当我使用 Lucene 进行搜索时,我会得到准确查询的响应,但不会得到模糊查询的响应(尽管正确地转义了查询文本)。

例如,给定一个值为“192:d4e1GDZYDUZrw9AfCB+A66ancCZmx9n2P:2e1GW18A66ac/YP”的字段,以下查询产生一条记录:

SELECT FROM Snippet WHERE ssdeep LUCENE "192\:d4e1GDZYDUZrw9AfCB\+A66ancCZmx9n2P\:2e1GW18A66ac\/YP"

虽然此查询没有产生任何记录:

SELECT FROM Snippet WHERE ssdeep LUCENE "192\:d4e1GDZYDUZrw9AfCB\+A66ancCZmx9n2P\:2e1GW18A66ac\/YP~0.9"

我想知道是什么阻止了 Lucene 找到近似结果?更具体地说,是 Lucene(或 KeywordAnalyzer)不适合模糊搜索此类字符串,还是 Lucene 和 OrientDB 之间的接口才是原因?

即我在同一个数据库上有其他全文 Lucene 索引可以工作,但所有这些字段都包含普通文本,并使用简单或标准分析器进行分析。这是我真正需要全文索引的唯一字段,但它不起作用。

问题是字母大小写。 StandardAnalyzer、SimpleAnalyzer 和 EnglishAnalyzer 在索引术语之前都是小写文本。 KeywordAnalyzer 没有。

由于不分析通配符、模糊和其他扩展的多术语查询,因此默认情况下,QueryParser 会将这些类型的查询小写。

我不太了解 OrientDB 公开了哪些 Lucene 以允许您有效地执行此操作,但 Lucene 中的两个最佳解决方案是:

  1. 禁用 QueryParser 小写这些类型的查询:

    queryParser.setLowercaseExpandedTerms(false);
    
  2. 使用结合了 KeywordTokenizer 和 LowerCaseFilter 的自定义分析器:

    public class LowercaseKeywordAnalyzer extends Analyzer {
        @Override
        protected TokenStreamComponents createComponents(String fieldName) {
            Tokenizer source = new KeywordTokenizer();
            TokenStream filter = new LowerCaseFilter(source);
            return new TokenStreamComponents(source, filter);
        }
    }
    

我不知道这些是否以及如何在 OrientDB 中公开,但希望这能为您指明正确的方向。