在 Lucene 中组合模糊查询和 SpanNear 查询

Combining Fuzzy and SpanNear Queries in Lucene

我在 Lucene 中使用模糊查询在输入 string/document 中模糊地搜索名字和姓氏(每个编辑距离为 2)。

我进一步期望这两个术语通过使用 SpanNearQuery 彼此非常接近(在此示例中,最多相隔 3 个术语)。我也不希望顺序很重要。

我构建查询的代码:

FuzzyQuery firstNameQuery = new FuzzyQuery(new Term("text", firstName), 2);
FuzzyQuery lastNameQuery = new FuzzyQuery(new Term("text", lastName), 2);

SpanQuery[] clauses = new SpanQuery[] {
    new SpanMultiTermQueryWrapper<MultiTermQuery>(firstNameQuery),
    new SpanMultiTermQueryWrapper<MultiTermQuery>(lastNameQuery)
};
SpanNearQuery spanNearQuery = new SpanNearQuery(clauses, 3, false);

我现在在单元测试中看到的是,levenshstein 距离为 1 的项似乎有效,因此 "John Doa"、"Jon Dox" 等将匹配 "John Doe",但是levenshstein 距离 2 不会,例如"Johnnie Doe" 将不匹配。

跨度长度工作正常,我最多可以在 first/last 个名称之间有 3 个术语。

谁能告诉我我做错了什么?

更新 1

抱歉,我搞砸了我在这里设计的示例,出于隐私原因没有使用真实数据。

我看到的是查询完全没有按照我想象的方式工作。

输入字符串:"Patient: John Doe" 查询:spanNear([SpanMultiTermQueryWrapper(text:John~2), SpanMultiTermQueryWrapper(text:Doe~2)], 3, false)

这不会产生命中,即使这些术语应该完全匹配(编辑距离为 0)。

Lucene 4.x fuzzy 将匹配每个术语 2 或更小的编辑距离,并且您的用例每个术语的距离大于 2(John 和 Johnnie 的距离为 3)。

在我看来,不太推荐使用 Lucene 内置的模糊来进行名称匹配,因为它不适用于冗长的名称(因为每个词的距离小于 2),而且速度较慢,因为它使用有限状态来查找最佳匹配。

最好和最快的方法是使用 "n-gram" 方法进行模糊匹配(三元组模糊匹配很常见!)

更新: 看起来你可能对大写小写有问题,据我所知,lucene 会丢弃用于模糊搜索的查询分析器。

你可以尝试使用 "john" 和 "doe"(均为小写)作为你的名字和姓氏吗?如果可行,请告诉我。