短语查询和使用 shingle 过滤器有啥区别?

Posted

技术标签:

【中文标题】短语查询和使用 shingle 过滤器有啥区别?【英文标题】:What is the difference between a phrase query and using a shingle filter?短语查询和使用 shingle 过滤器有什么区别? 【发布时间】:2012-01-24 20:01:56 【问题描述】:

我目前正在使用 lucene 索引网页。目的是能够快速提取出哪个页面包含某个表达(通常是 1、2 或 3 个单词),以及页面中还有哪些其他单词(或其中 1 到 3 个的组)。 这将用于构建/丰富/更改同义词库(固定词汇表)。

从我找到的文章看来,问题在于找到n-grams(或木瓦)。

Lucene 有一个ShingleFilter、一个ShingleMatrixFilter 和一个ShingleAnalyzerWrapper,似乎与这个任务有关。

通过presentation,我了解到 Lucene 还可以搜索由固定数量的单词分隔的术语(称为 slops)。提供了一个示例here。

但是,我不清楚这些方法之间的区别?它们是根本不同,还是您必须做出的性能/索引大小选择?

ShingleMatrixFilter 和 ShingleFilter 有什么区别?

希望 Lucene 大师能找到这个问题,并回答 ;-) !

【问题讨论】:

【参考方案1】:

使用词组与带状疱疹的区别主要在于表现和评分。

当在索引中有单个单词的典型情况下使用短语查询(比如“foo bar”)时,短语查询必须遍历“foo”和“bar”的倒排索引,并找到同时包含这两个词的文档术语,然后在每个文档中遍历他们的位置列表,以找到“foo”出现在“bar”之前的位置。

这对性能和得分都有一定的影响:

    位置 (.prx) 必须被索引和搜索,这就像倒排索引的额外“维度”,会增加索引和搜索时间 因为倒排索引中只出现了单个词,所以没有计算出真正的“短语 IDF”(这可能不会影响您)。因此,这是根据 IDF 项的总和进行近似计算的。

另一方面,如果您使用 shingles,那么您也在索引单词 n-gram,换句话说,如果您使用 shingling 的大小为 2,那么索引中还会包含诸如“foo bar”之类的术语。这意味着对于这个短语查询,它将被解析为一个简单的 TermQuery,而不使用任何位置列表。由于它现在是一个“真正的术语”,因此 IDF 这个短语将是准确的,因为我们确切地知道这个“术语”存在多少文档。

但使用带状疱疹也有一些成本:

    增加了术语字典、术语索引和发布列表大小,尽管这可能是一个公平的权衡,特别是如果您完全使用 Field.setIndexOptions 完全禁用位置。 在索引分析阶段的一些额外成本:尽管 ShingleFilter 优化得很好并且速度非常快。 没有明显的方法来计算“草率的短语查询”或不精确的短语匹配,尽管这可以近似,例如对于带有大小为 2 的带状疱疹的“foo bar baz”短语,您将有两个标记:foo_bar、bar_baz,并且您可以通过 lucene 的一些其他查询(如 BooleanQuery)实现搜索以获得不精确的近似值。

一般来说,使用像带状疱疹或 CommonGrams 之类的东西来索引 word-ngram 只是一种权衡(相当专家),以降低位置查询的成本或提高短语评分。

但是这些东西有实际的用例,这里有一个很好的例子: http://www.hathitrust.org/blogs/large-scale-search/slow-queries-and-common-words-part-2

【讨论】:

感谢您的详细回答(已接受)。能否评论一下 ShingleFilter 和 ShingleMatrixFilter 之间的区别? 确实很好的解释。这篇文章通过一些实例帮助我理解了带状疱疹:elastic.co/blog/searching-with-shingles

以上是关于短语查询和使用 shingle 过滤器有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Servlet 过滤器和 Jersey 过滤器有啥区别?

C 和 C++ 中的“通过引用传递”到底有啥区别?

for example和example有啥区别?

多表连接查询中,“on”和“where”有啥区别吗?

这两个媒体查询有啥区别? [复制]

Servlet 过滤器和 Servlet 上下文侦听器有啥区别?