【问题标题】:Lucene Phrase query with incomplete words带有不完整单词的 Lucene 短语查询
【发布时间】:2018-09-25 07:42:27
【问题描述】:

我已经用 StandandAnalyzer 实现了 RamDirectory,并将数据存储在 Lucene 缓存中,我在 Lucene 中添加了如下数据:

final Document document = new Document();

final IndexableField id = new StringField("placeId", place.getPlaceId(), Field.Store.YES);
final IndexableField name = new TextField("name", place.getName().toLowerCase(), Field.Store.YES);
final IndexableField location = new LatLonPoint("location", place.getLatitude(), place.getLongitude());
final IndexableField city = new StringField("city", place.getCity(), Field.Store.YES);

document.add(id);
document.add(name);
document.add(location);
document.add(city);

我实现了两种搜索数据的方法,一种是定义半径内的附近地点,效果很好,另一种是按名称搜索地点。 我们还必须在按名称搜索时实现自动完成功能。

我已经实现了按名称搜索如下:

QueryParser parser = new QueryParser("name", analyzer);
return parser.createPhraseQuery("name", searchStr, 2);

现在我有了一个名字,可以说“汤姆诊所和药房”。

如果我使用以下短语进行搜索,我会返回结果:

  1. 汤姆
  2. 汤姆诊所
  3. 汤姆药房

这很好,但如果用户键入“Tom clini”或“Tom pharma”,Lucene 不会返回任何结果。

我尝试在 searchStr 的末尾添加一个“*”,尝试将短语传递给通配符查询(它在单个单词上工作正常,但在多个单词上失败)。

另外我想添加一些模糊性,以便可以处理错别字,我是 Lucene 的新手,不知道从这里做什么,所以尽你所能帮助我!

P.S 它的 Lucene 7.3

【问题讨论】:

  • 你用的是什么分析仪?
  • 标准分析仪
  • 你用例来做前缀搜索吗?或者例如,如果您只是搜索药房,您还想匹配具有“汤姆诊所和药房”的文档吗?

标签: java lucene


【解决方案1】:

在这些情况下,最好的办法始终是寻找好的资源。我可以推荐以下书籍

。 特别是,您可能对以下其中一项或两项都感兴趣:

模糊查询

Lucene 的模糊搜索实现基于 Levenshtein 距离。 它比较两个字符串并找出单个字符的数量 将一个字符串转换为另一个字符串所需的更改。这 结果数字表示两个字符串的接近程度。在一个 模糊搜索,使用阈值编辑次数来确定是否 两个字符串匹配。要在 QueryParser 中触发模糊匹配,您 可以使用波浪号 ~ 字符。有几个配置 QueryParser 来调整这种类型的查询。这是一个代码

queryParser.setFuzzyMinSim(2f);
queryParser.setFuzzyPrefixLength(3);
Query query = queryParser.parse("hump~");

本示例将返回第一、第二和第四句作为 模糊匹配将驼峰匹配到驼峰,因为这两个词被遗漏了 由两个字符。我们将模糊查询调整为最小相似度 本例中有两个。

PhraseQuery 和 MultiPhraseQuery

一个 PhraseQuery 匹配一个特定的术语序列,而一个 MultiPhraseQuery 为您提供了匹配多个词条的选项 相同的位置。例如,MultiPhrasQuery 支持一个短语,例如 humpty (dumpty OR together) 在位置 0 中匹配 humpty 和dumpty或一起在位置1。

怎么做...

这是一个代码 sn-p 来演示这两种查询类型:

PhraseQuery query = new PhraseQuery();
query.add(new Term("content", "humpty"));
query.add(new Term("content", "together"));
MultiPhraseQuery query2 = new MultiPhraseQuery();
Term[] terms1 = new Term[1];
terms1[0] = new Term("content", "humpty");
Term[] terms2 = new Term[2];
terms2[0] = new Term("content", "dumpty");
terms2[1] = new Term("content", "together");
query2.add(terms1);
query2.add(terms2);

它是如何工作的……

第一个查询 PhraseQuery 一起搜索短语 humpty。 第二个查询 MultiPhraseQuery 搜索 短语 humpty (dumpty OR together)。第一个查询将返回 我们设置中的第四句,而第二个查询将返回 第一、二、四句。请注意,在 MultiPhraseQuery 中,多个 将相同位置的词作为数组添加。

但是,直接处理 Lucene 的应用程序并不多,更常见的是使用 SolrElastic Search。两者都在引擎盖下使用 Lucene,但包装精美。可能值得一看。

【讨论】:

  • @Nitesh 这是你要找的吗?
  • 感谢您的洞察力。我知道 solr 和弹性。不幸的是,我们不能为一个小功能添加一个全新的组件到系统中。好吧,我尝试了这些查询类型。但是,后来我意识到——我需要介于 n-gram 和模糊之间的东西。不过,在过去的几个月里,我找不到太多时间来解决这个问题。
【解决方案2】:

使用模糊查询
您可以在您喜欢搜索的字段上使用模糊查询。请注意,您使用 TextField 是因为这些字段将被分析(而 StringField 不会)并用于全文搜索。

在此处阅读更多信息FuzzyQuery


使用 SpanNear 查询
匹配彼此靠近的跨度。可以指定 slop、中间不匹配位置的最大数量,以及匹配是否需要按顺序排列。

在此处阅读更多信息SpanNearQuery

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多