Lucene模糊搜索短语(FuzzyQuery + SpanQuery)

use*_*171 11 lucene fuzzy-search

我正在寻找一种编码lucene模糊查询的方法,该查询搜索与精确短语相关的所有文档.如果我搜索"mosa employee appreciata",将返回包含"大多数员工欣赏"的文档作为结果.

我试着用:

FuzzyQeury = new FuzzyQuery(new Term("contents","mosa employee appreicata"))
Run Code Online (Sandbox Code Playgroud)

不幸的是,它凭经验不起作用.FuzzyQuery采用编辑器距离,理论上,"mosa员工欣赏"应与"大多数员工欣赏"相匹配,提供适当的距离.这看起来有点奇怪.

有线索吗?谢谢.

fem*_*gon 16

这里有两个可能的问题.第一:我猜测正在分析"内容"字段,以便"大多数员工apreciate"不是一个术语,而是三个术语.在这种情况下,定义为单个术语是不合适的.

但是,即使列出的内容是单个术语,我们遇到的第二个可能的问题是术语之间的距离太大以获得匹配.之间的Damerau-Levenshtein距离mosa employee appreicatamost employees appreciate为4(的大致距离,顺便说一句,在拼写"Damerau -莱文斯坦"我的平均第一枪和正确的拼写之间).模糊查询,从4.0开始,由于性能限制而处理不超过2的编辑距离,并且假设较大距离通常不是特别相关.

如果您需要使用模糊术语执行短语查询,您应该查看MultiPhraseQuery或者组合一组SpanQueries(特别是SpanMultiTermQueryWrapperSpanNearQuery)来满足您的需求.

SpanQuery[] clauses = new SpanQuery[3];
clauses[0] = new SpanMultiTermQueryWrapper(new FuzzyQuery(new Term("contents", "mosa")));
clauses[1] = new SpanMultiTermQueryWrapper(new FuzzyQuery(new Term("contents", "employee")));
clauses[2] = new SpanMultiTermQueryWrapper(new FuzzyQuery(new Term("contents", "appreicata")));
SpanNearQuery query = new SpanNearQuery(clauses, 0, true)
Run Code Online (Sandbox Code Playgroud)

由于没有任何单个术语的编辑距离大于2,因此这应该更有效.


use*_*171 -1

femtoRgon 的回答非常棒!谢谢。

还有另一种方法可以解决这个问题。

//declare a mutilphrasequery
MultiPhraseQuery childrenInOrder = new MultiPhraseQuery();

//user fuzzytermenum to enumerate your query string
FuzzyTermEnum fuzzyEnumeratedTerms1 = new FuzzyTermEnum(reader, new Term(searchField,"mosa"));
FuzzyTermEnum fuzzyEnumeratedTerms2 = new FuzzyTermEnum(reader, new Term(searchField,"employee"));
FuzzyTermEnum fuzzyEnumeratedTerms3 = new FuzzyTermEnum(reader, new Term(searchField,"appreicata"));

//this basically pull out the possbile terms from the index             
Term termHolder1 = fuzzyEnumeratedTerms1.term();
Term termHolder2 = fuzzyEnumeratedTerms2.term();
Term termHolder3 = fuzzyEnumeratedTerms3.term();

//put the possible terms into multiphrasequery
if (termHolder1==null){
    childrenInOrder.add(new Term(searchField,"mosa"));
}else{
    childrenInOrder.add(fuzzyEnumeratedTerms1.term());
}

if (termHolder2==null){
    childrenInOrder.add(new Term(searchField,"employee"));
}else{
    childrenInOrder.add(fuzzyEnumeratedTerms2.term());
}

if (termHolder3==null){
    childrenInOrder.add(new Term(searchField,"appreicata"));
}else{
    childrenInOrder.add(fuzzyEnumeratedTerms3.term());
}


//close it - it is important to close it
fuzzyEnumeratedTerms1.close();
fuzzyEnumeratedTerms2.close();
fuzzyEnumeratedTerms3.close();
Run Code Online (Sandbox Code Playgroud)

  • 你用的是哪个版本的lucene?我似乎找不到 4.6 的 FuzzyTermEnum api。在 4.6 中只有 FuzzyTermsEnum 具有不同的构造函数 (3认同)
  • 恕我直言,这实际上并没有达到您的预期。也许适合您的简单示例,但不适用于包含更多文本的更复杂文档。因为 FuzzyTermEnum 没有给出索引中较大文档中的正确术语... (2认同)