Microfaster, 让我们略微加速

elasticsearch[5.5]全文匹配 —— Common Terms Query常用术语查询

2018-12-18 11:42:43 lvesu (1414阅读)

标签 Elasticsearch

常用术语查询

该common术语查询是一个现代的替代提高了精确度和搜索结果的召回(采取禁用词进去),在不牺牲性能的禁用词。


问题

查询中的每个术语都有成本。搜索"The brown fox" 需要三个术语查询,每个查询一个"the","brown"并且 "fox"所有查询都针对索引中的所有文档执行。查询"the"可能与许多文档匹配,因此对相关性的影响比其他两个术语小得多。


以前,这个问题的解决方案是忽略高频率的术语。通过将其"the"视为停用词,我们减少了索引大小并减少了需要执行的术语查询的数量。


这种方法的问题在于,虽然停用词对相关性的影响很小,但它们仍然很重要。如果我们删除了停用词,我们就会失去精确度(例如,我们无法区分"happy" 和"not happy"),并且我们会失去回忆(例如,文本在索引中"The The"或者 "To be or not to be"根本不存在)。


解决方案

该common术语的查询将所述查询术语分为两组:更重要(即低频率而言)和不太重要的(即,高频率而言这将先前已停用词)。


首先,它搜索与更重要的术语匹配的文档。这些术语出现在较少的文档中,对相关性有较大影响。


然后,它对不太重要的术语执行第二次查询 - 这些术语经常出现并且对相关性的影响很小。但是,它不是计算所有匹配文档的相关性分数,而是仅计算_score已经与第一个查询匹配的文档。通过这种方式,高频项可以改善相关性计算,而无需支付性能不佳的成本。


如果查询仅包含高频术语,则单个查询将作为AND(连接)查询执行,换句话说,所有术语都是必需的。即使每个单独的术语与许多文档匹配,术语组合也会将结果集缩小到最相关的范围。单个查询也可以作为OR特定的 查询执行minimum_should_match,在这种情况下,应该使用足够高的值。


根据条件将术语分配给高频或低频组 cutoff_frequency,可以将其指定为绝对频率(>=1)或相对频率(0.0 .. 1.0)。(请记住,文档频率是按照每个分片级别计算的,如博客文章中所述, 相关性已被破坏。)


也许这个查询最有趣的属性是它自动适应域特定的停用词。例如,在视频托管网站上,常见的术语如"clip"或"video"将自动表现为停用词而无需维护手动列表。


示例


在此示例中,文档频率大于0.1%(例如"this"和"is")的单词将被视为常用术语。

GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "this is bonsai cool",
                "cutoff_frequency": 0.001
            }
        }
    }
}

可以使用minimum_should_match (high_freq,low_freq),low_freq_operator(默认"or")和high_freq_operator(默认"or")参数控制应匹配的术语 数。


低频方面,设置low_freq_operator以"and"使所需的所有条件:

GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "nelly the elephant as a cartoon",
                "cutoff_frequency": 0.001,
                "low_freq_operator": "and"
            }
        }
    }
}

这大致相当于:

GET /_search
{
    "query": {
        "bool": {
            "must": [
            { "term": { "body": "nelly"}},
            { "term": { "body": "elephant"}},
            { "term": { "body": "cartoon"}}
            ],
            "should": [
            { "term": { "body": "the"}},
            { "term": { "body": "as"}},
            { "term": { "body": "a"}}
            ]
        }
    }
}

或者用于 minimum_should_match 指定必须存在的低频项的最小数量或百分比,例如:

GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "nelly the elephant as a cartoon",
                "cutoff_frequency": 0.001,
                "minimum_should_match": 2
            }
        }
    }
}

这大致相当于:

GET /_search
{
    "query": {
        "bool": {
            "must": {
                "bool": {
                    "should": [
                    { "term": { "body": "nelly"}},
                    { "term": { "body": "elephant"}},
                    { "term": { "body": "cartoon"}}
                    ],
                    "minimum_should_match": 2
                }
            },
            "should": [
                { "term": { "body": "the"}},
                { "term": { "body": "as"}},
                { "term": { "body": "a"}}
                ]
        }
    }
}

minimum_should_match 使用附加low_freqhigh_freq参数可以对低频和高频术语应用不同的 术语 。以下是提供其他参数的示例(请注意结构的变化):

GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "nelly the elephant not as a cartoon",
                "cutoff_frequency": 0.001,
                "minimum_should_match": {
                    "low_freq" : 2,
                    "high_freq" : 3
                }
            }
        }
    }
}

这大致相当于:

GET /_search
{
    "query": {
        "bool": {
            "must": {
                "bool": {
                    "should": [
                    { "term": { "body": "nelly"}},
                    { "term": { "body": "elephant"}},
                    { "term": { "body": "cartoon"}}
                    ],
                    "minimum_should_match": 2
                }
            },
            "should": {
                "bool": {
                    "should": [
                    { "term": { "body": "the"}},
                    { "term": { "body": "not"}},
                    { "term": { "body": "as"}},
                    { "term": { "body": "a"}}
                    ],
                    "minimum_should_match": 3
                }
            }
        }
    }
}

在这种情况下,这意味着高频项在至少有三个时对相关性有影响。但是minimum_should_match 对于高频术语最有趣的用法 是当只有高频术语时:

GET /_search
{
    "query": {
        "common": {
            "body": {
                "query": "how not to be",
                "cutoff_frequency": 0.001,
                "minimum_should_match": {
                    "low_freq" : 2,
                    "high_freq" : 3
                }
            }
        }
    }
}

这大致相当于:

GET /_search
{
    "query": {
        "bool": {
            "should": [
            { "term": { "body": "how"}},
            { "term": { "body": "not"}},
            { "term": { "body": "to"}},
            { "term": { "body": "be"}}
            ],
            "minimum_should_match": "3<50%"
        }
    }
}

然后,高频率生成的查询的限制性略低于AND

common术语查询还支持boostanalyzer作为参数。


https://blog.csdn.net/ctwy291314/article/details/82836514


https://www.elastic.co/guide/en/elasticsearch/reference/5.5/query-dsl-common-terms-query.html


北京半月雨文化科技有限公司.版权所有 京ICP备12026184号