【问题标题】:How to perform a wildcard search in Lucene如何在 Lucene 中执行通配符搜索
【发布时间】:2011-08-10 10:45:34
【问题描述】:

我知道 Lucene 广泛支持通配符搜索,而且我知道您可以搜索以下内容:

Stackover*(将返回 Stackoverflow

也就是说,我的用户对学习查询语法不感兴趣。 Lucene 可以使用开箱即用的分析器执行这种类型的通配符搜索吗?还是应该在每个搜索查询中附加“*”?

【问题讨论】:

    标签: search lucene search-engine lucene.net wildcard


    【解决方案1】:

    用字符串操作来做这件事很难做到正确,特别是因为 QueryParser 支持提升、短语等。

    您可以使用 QueryVisitor 将 TermQuery 重写为 PrefixQuery。

    public class PrefixRewriter : QueryVisitor {
        protected override Query VisitTermQuery(TermQuery query) {
            var term = query.GetTerm();
            var newQuery = new PrefixQuery(term);
            return CopyBoost(query, newQuery);
        }
    }
    

    QueryVisitor 基类目前可以在gitlab 找到。

    代码最初发布在 blog post 上,现在已失效。博文还是available at archive.org

    【解决方案2】:

    如果您正在考虑将每个查询变成通配符,我会问自己以下问题:

    1. Lucene 是完成这项工作的最佳工具吗?默认情况下,通配符重写为恒定分数查询,这意味着您完全放弃了相关性排名,不再“搜索”而是“匹配”。也许对于您的应用程序而言,搜索引擎库不是最佳解决方案,而另一种工具(例如数据库)会更好。
    2. 如果对#1 的回答仍然是“是”,那么我建议您查看您要解决的确切相关问题是什么。例如,如果您希望查询匹配复合词或词干词,则可以改为在分析链中添加分解器或词干分析器。您还可以考虑使用 n-gram 索引技术作为另一种替代方法。

    【讨论】:

    • LUCENE 通配符搜索对于大量记录仍然比 SQL Server 快。
    【解决方案3】:

    如果我想做类似的事情,我通常会在搜索之前格式化术语,例如

    searchTerm = QueryParser.EscapesearchTerm);
    if(!searchTerm.EndsWith(" "))
    {
        searchTerm = string.Format("{0}*", searchTerm);
    }
    

    这将转义人们输入的任何特殊字符。 如果该术语没有以空格结尾,则在末尾附加一个 *。 因为 * 本身会导致解析异常。

    【讨论】:

      猜你喜欢
      • 2010-11-01
      • 2018-04-20
      • 2014-06-11
      • 1970-01-01
      • 2022-01-11
      • 2014-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多