在Elasticsearch的查询DSL中,must和filter有什么区别?

115

我对Elasticsearch很陌生,而且我对must和filter之间的区别感到困惑。我想在我的术语中执行一个and操作,所以我这样做了:

POST /xyz/_search

{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "city": "city1"
                    }
                },
                {
                    "term": {
                        "saleType": "sale_type1"
                    }
                }
            ]
        }
    }
}

使用这样的过滤器,我得到了符合两个条件的所需结果

POST /xyz/_search

{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "city": "city1"
                    }
                }
            ],
            "filter": {
                "term": {
                    "saleType": "sale_type1"
                }
            }
        }
    }
}

我得到了相同的结果,那么何时应该使用must,何时应该使用filter?有什么区别?

2个回答

123

must(必须)对得分有贡献,而在filter(过滤器)中则会忽略得分。

mustfilter中,查询条件(子句)都必须出现在匹配的文档中。这就是获得相同结果的原因。

您可以查看此链接

得分

每个文档的相关度得分以正浮点数表示,称为_score。得分越高,文档越相关。

查询子句为每个文档生成一个_score

了解得分的计算方式,请参阅此链接


41
不太回答“必须”与“过滤器”何时使用的问题。也就是说,什么情况下得分很重要? - intiha
35
使用filter能够更快地进行搜索,因为不需要计算分数或排序。当您关心搜索词的出现次数、匹配文档的长度或者想要在查询中添加 boost 来提高匹配文档的排名时,评分就变得重要了。 - Cardin
2
如果您的所有查询都是布尔型的话,分数并不重要。在过滤器中使用的子句可以被缓存:“过滤器上下文中执行过滤器子句,这意味着评分被忽略,子句被视为可缓存。Ref: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html” - Paul
我认为当您有一个复合查询时,内部查询的分数用于计算总体分数也很重要。对于“must_not”也是如此。 - moon
只是补充一下@Cardin的评论。我在一个相对较小的数据集(2k条记录)上执行了相同的查询,第一次使用'must',第二次使用过滤器。使用'must',它花费了20毫秒,而使用过滤器则花费了6毫秒。当你所需要的仅仅是一个'filter'时,避免使用'must'。 - Tiago Duque
2
@Cardin,你的评论应该是这个问题的最佳答案。尝试将其写成一个答案。 - Yahya

8

must 会为每个匹配的文档返回一个分数。这个分数可以帮助您对匹配的文档进行排名,并且可以使用每个文档的分数大小比较文档之间的相关性。

通过这个方法,您可以说,文档1比文档2相关性高3倍。或者说文档1到7比文档8及以后的文档更相关。

关于如何确定相对分数的方法,您可以参考下面的参考资料。
简单来说,它与文档中术语出现的次数、文档长度以及数据库索引中平均术语出现的次数有关。


filter 不会返回分数。我们只能说,所有匹配的文档都是相关的。但它不能帮助评估哪个比另一个更相关。你可以把 filter 看作是一个只有两个分数(零或非零)的 must,其中所有零分文档都被删除。

filter 对于只想要为例如所有属于“宠物”主题的文档设置白名单/黑名单的情况非常有用。


总之,在决定何时使用什么时,有三个要点会帮助您:

  1. 当通过相关性比较/排名文档时,must是唯一的选择
  2. 如果您不关心分数/排名,则使用filter
  3. filter更快,因为Elasticsearch无需计算得分。

参考资料:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接