我看不到任何关于何时应该使用查询或过滤器或两者的某种组合的描述。它们之间的区别是什么?有人能解释一下吗?


当前回答

自Elasticsearch版本2以来,过滤器和查询已经合并,任何查询子句都可以用作过滤器或查询(取决于上下文)。与版本1一样,过滤器是缓存的,如果评分不重要,就应该使用它。

来源:https://logz.io/blog/elasticsearch-queries/

其他回答

区别很简单:过滤器被缓存,不影响分数,因此比查询快。看看这里。假设一个查询通常是用户键入的并且几乎不可预测的,而过滤器帮助用户缩小搜索结果,例如使用facet。

除此之外,很少有其他的。 首先应用筛选器,然后对其结果处理查询。为了存储每个文档的二进制真/假匹配,使用了bitSet数组。 这个BitSet数组在内存中,它将在第二次查询过滤器时使用。这样,使用bitset数组数据结构,我们就能够利用缓存的结果。

这里还有一点需要注意,过滤器缓存仅在执行请求时创建,因此只有从第二次命中开始,我们才真正获得缓存的优势。

但你可以使用更温暖的API来解决这个问题。当你在一个更温暖的API上用过滤器注册一个查询时,它将确保在一个新的段出现时对它执行。因此,我们将从第一次执行本身获得一致的速度。

官方文件是这么说的:

作为一般规则,应该使用过滤器而不是查询: 用于二进制是/否搜索 用于查询确切的值


作为一般规则,应该使用查询而不是过滤器: 全文检索 结果取决于相关性评分

过滤器->这个文档匹配吗?是或否的二元答案

查询->这个文档匹配吗?匹配度如何?使用得分

一个例子(你自己试试)

说索引myindex包含三个文档:

curl -XPOST localhost:9200/myindex/mytype  -d '{ "msg": "Hello world!" }'
curl -XPOST localhost:9200/myindex/mytype  -d '{ "msg": "Hello world! I am Sam." }'
curl -XPOST localhost:9200/myindex/mytype  -d '{ "msg": "Hi Stack Overflow!" }'

查询:文档与查询匹配的程度

查询hello sam(使用关键字must)

curl localhost:9200/myindex/_search?pretty  -d '
{
  "query": { "bool": { "must": { "match": { "msg": "hello sam" }}}}
}'

文档“Hello world!”I am Sam.”的得分比“Hello world!”高,因为前者与查询中的两个单词都匹配。对文档进行评分。

"hits" : [
   ...
     "_score" : 0.74487394,
     "_source" : {
       "name" : "Hello world! I am Sam."
     }
   ...
     "_score" : 0.22108285,
     "_source" : {
       "name" : "Hello world!"
     }
   ...

筛选:文档是否与查询匹配

过滤hello sam(使用关键字过滤器)

curl localhost:9200/myindex/_search?pretty  -d '
{
  "query": { "bool": { "filter": { "match": { "msg": "hello sam" }}}}
}'

返回包含hello或sam的文档。文档不记分。

"hits" : [
   ...
     "_score" : 0.0,
     "_source" : {
       "name" : "Hello world!"
     }
   ...
     "_score" : 0.0,
     "_source" : {
       "name" : "Hello world! I am Sam."
     }
   ...

除非您需要全文搜索或评分,否则首选过滤器,因为Elasticsearch将自动缓存频繁使用的过滤器,以提高性能。参见Elasticsearch:查询和过滤上下文。