停用词与性能

edit

保留停用词最大的缺点就影响搜索性能。使用 Elasticsearch 进行全文搜索,它需要为所有匹配的文档计算相关度评分 _score 从而返回最相关的前 10 个文档。

通常大多数的单词在所有文档中出现的频率低于0.1%,但是有少数词(例如 the )几乎存在于所有的文档中。假设有一个索引含有100万个文档,查询 quick brown fox 词组,能够匹配上的可能少于1000个文档。但是如果查询 the quick brown fox 词组,几乎需要对索引中的100万个文档进行评分和排序,只是为了返回前 10 名最相关的文档。

问题的关键是 the quick brown fox 词组实际是查询 thequickbrownfox— 任何文档即使它什么内容都没有而只包含 the 这个词也会被包括在结果集中。因此,我们需要找到一种降低待评分文档数量的方法。

and 操作符 (and Operator)

edit

我们想要减少待评分文档的数量,最简单的方式就是在and 操作符 match 查询时使用 and 操作符,这样可以让所有词都是必须的。

以下是 match 查询:

{
    "match": {
        "text": {
            "query":    "the quick brown fox",
            "operator": "and"
             }
    }
}

上述查询被重写为 bool 查询如下:

{
    "bool": {
        "must": [
            { "term": { "text": "the" }},
            { "term": { "text": "quick" }},
            { "term": { "text": "brown" }},
            { "term": { "text": "fox" }}
        ]
    }
}

bool 查询会智能的根据较优的顺序依次执行每个 term 查询:它会从最低频的词开始。因为所有词项都必须匹配,只要包含低频词的文档才有可能匹配。使用 and 操作符可以大大提升多词查询的速度。

最少匹配数(minimum_should_match)

edit

在精度匹配控制精度的章节里面,我们讨论过使用 minimum_should_match 配置去掉结果中次相关的长尾。虽然它只对这个目的奏效,但是也为我们从侧面带来一个好处,它提供 and 操作符相似的性能。

{
    "match": {
        "text": {
            "query": "the quick brown fox",
            "minimum_should_match": "75%"
        }
    }
}

在上面这个示例中,四分之三的词都必须匹配,这意味着我们只需考虑那些包含最低频或次低频词的文档。 相比默认使用 or 操作符的简单查询,这为我们带来了巨大的性能提升。不过我们有办法可以做得更好……