【问题标题】:Lucene - Wildcards in phrasesLucene - 短语中的通配符
【发布时间】:2010-11-08 11:34:14
【问题描述】:

我目前正在尝试使用 Lucene 搜索填充在索引中的数据。

我可以通过将其括在括号中来匹配确切的短语(即“处理文档”),但无法让 Lucene 通过执行任何类型的“处理文档*”来找到该短语。

明显的区别是末尾的通配符。

我目前正在尝试使用 Luke 来查看和搜索索引。 (解析时会去掉短语末尾的星号)

在数据周围添加引号似乎是主要的罪魁祸首,因为搜索 document* 会起作用,但 "document*" 不起作用

任何帮助将不胜感激

【问题讨论】:

  • 摆弄这个。可能的解决方法。有没有办法使用通配符进行邻近搜索?不过,似乎这可能会对性能造成重大影响。

标签: c# .net lucene lucene.net


【解决方案1】:

Lucene 2.9 有ComplexPhraseQueryParser 可以处理短语中的通配符。

【讨论】:

  • 模糊逻辑可以应用于短语吗?例如,将“Elton John”与“Alton Jon”匹配。我有一个全名列表,想建议匹配全名,而不是单词,拼写不同。
【解决方案2】:

您正在寻找的是FuzzyQuery,它允许您根据Levenshtein distance 搜索具有相似词的结果。或者,如果单词的顺序不重要,您可能还想考虑使用 slop of PhraseQuery也可在 MultiPhraseQuery 中使用)。

【讨论】:

  • 如何在短语上应用 FuzzyQuery?例如,将“Elton John”与“Alton Jon”匹配。我有一个全名列表,并希望建议匹配名称与拼写差异。
【解决方案3】:

QueryParser 不仅不支持短语中的通配符,而且 PhraseQuery 本身只支持术语。 MultiPhraseQuery 更接近了,但正如其摘要所说,您仍然需要自己枚举 IndexReader.terms 以匹配通配符。

【讨论】:

    【解决方案4】:

    似乎默认的 QueryParser 无法处理这个问题。您可能可以为短语中的通配符创建自定义 QueryParser。如果您的示例具有代表性,stemming 可能会解决您的问题。请阅读PorterStemFilter 的文档,看看它是否合适。

    【讨论】:

      【解决方案5】:

      另一种选择是使用 NGrams,特别是 EdgeNGram。 http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters#solr.EdgeNGramFilterFactory

      这将为 ngram 或部分单词创建索引。 最小 ngram 大小为 5 且最大 ngram 大小为 8 的文档将索引: 文档 纪录片 文档 文件

      索引大小和时间需要权衡取舍。 Solr 书籍之一作为粗略指南引用: 索引需要 10 倍的时间 使用 5 倍以上的磁盘空间 创建 6 倍的不同术语。

      不过,EdgeNGram 会做得更好。

      您确实需要确保您没有在查询中提交通配符。 由于您没有进行通配符搜索,因此您正在匹配 ngram(单词的一部分)上的搜索词。

      【讨论】:

        【解决方案6】:

        我也在寻找同样的东西,我发现 PrefixQuery 提供了诸如“处理文档*”之类的东西的 ua 组合。但问题是您正在搜索的字段应该被取消标记并以小写形式存储(原因是因为它是未标记的索引器不会将您的字段值保存为小写)才能使其正常工作。这是适用于我的 PrefixQuery 的代码:-

        List<SearchResult> results = new List<SearchResult>();
        Lucene.Net.Store.Directory searchDir = FSDirectory.GetDirectory(this._indexLocation, false);
        IndexSearcher searcher = new IndexSearcher( searchDir );
        Hits hits;
        
        BooleanQuery query = new BooleanQuery();
        query.Add(new PrefixQuery(new Term(FILE_NAME_KEY, keyWords.ToLower())), BooleanClause.Occur.MUST);
        hits = searcher.Search(query);
        this.FillResults(hits, results);
        

        【讨论】:

          【解决方案7】:

          使用斜率为 0 的 SpanNearQuery

          不幸的是,Lucene.Net 中没有 SpanWildcardQuery。要么您需要使用SpanMultiTermQueryWrapper,要么您可以毫不费力地将java version 转换为C#。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-08-07
            • 1970-01-01
            • 2013-09-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-01-16
            相关资源
            最近更新 更多