【问题标题】:Search for terms in the index which are a prefix of the search term or vice versa (!)在索引中搜索作为搜索词前缀的词,反之亦然 (!)
【发布时间】:2012-11-03 20:28:11
【问题描述】:

如果我搜索“bahnhofstrasse”,我希望 Lucene 查找包含术语“bahnhofstr”的文档,即,我不仅想查找包含我的搜索词作为前缀的术语的文档,而且还查找文档包含本身就是我的搜索词前缀的词...

我该怎么办?

【问题讨论】:

  • 相关(但没有给你正确的答案,只是说“是的,你可以”):stackoverflow.com/questions/10671755/…
  • 没有看到反之亦然的部分。所以你也想打“b”?有最小长度吗?
  • 是的,在某些情况下我也想点击“b”。想象一个只有内容“D”的字段“first_name”......

标签: java lucene


【解决方案1】:

我认为模糊查询可能对您最有帮助。这将根据与您的查询的 Levenshtein 距离对术语进行评分。如果没有指定最小相似度,它将有效地匹配每个可用的术语。这可能会使其性能不佳,但确实可以满足您的需求。

模糊查询由 ~ 字符表示,例如:

firstname:bahnhofstr~

或具有最小相似度(0 到 1 之间的数字,0 是最松散的,没有最小值)

firstname:bahnhofstr~0.4

或者,如果您正在构建自己的查询,请使用 FuzzyQuery

这与您指定的不完全一样,但却是最简单的接近方法。

就您正在寻找的内容而言,我不知道有一个简单的 Lucene 调用来完成它。我可能只是将术语拆分为一系列术语查询,您可以在查询字符串中表示如下:

firstname:b
firstname:ba
firstname:bah
firstname:bahn
firstname:bahnh
firstname:bahnho
firstname:bahnhof
firstname:bahnhofs
firstname:bahnhofst
firstname:bahnhofstr*

顺便说一句,我自己实际上不会为它生成查询字符串。我只是自己构建 TermQuery 和 PrefixQuery 对象。

评分会有点扭曲,我可能会更高地提升更长的查询以获得更好的排序,但这是我想到的方法,可以相当轻松地完成您正在寻找的内容。 DisjunctionMaxQuery 将帮助您将此类内容与其他术语一起使用并获得更合理的评分。

希望模糊查询对您有用。似乎是一个更好的解决方案。

如果您对这种性质的查询有很多需求,另一种选择可能是在索引时将字段标记为 n-gram(请参阅 NGramTokenizer),这将允许您有效地使用 NGramPhraseQuery 来达到你想要的结果。

【讨论】:

    【解决方案2】:

    如果我对您的理解正确,并且您的搜索字符串是一个确切的字符串,您可以在 Lucene 中设置 queryParser.setAllowLeadingWildcard(true); 以允许前导通配符搜索(这可能会或可能不会很慢 - 我已经看到它们相当快但在只有 60,000 多个 Lucene 文档的情况下)。

    您的示例查询语法可能类似于:

    *bahnhofstr bahnhofstr*
    

    或者可能(没有测试过)只是:

    *bahnhofstr*
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-30
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 2018-07-18
      相关资源
      最近更新 更多