查询与过滤器


198

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


46
官方文件实际上不是很清楚
geekazoid 2014年

2
像有看上去都出现一个页面,更先进的解释:elastic.co/guide/en/elasticsearch/guide/master/...
梅德Polushkin

6
值得一提的是,查询和过滤器将在ES 2.0中合并,因此,针对查询和过滤器的大部分描述和编写将不再适用。另请查看宣布此更改的官方博客文章
2015年

Answers:


201

区别很简单:过滤器被缓存并且不影响得分,因此比查询要快。也在这里看看。假设查询通常是用户输入的内容,并且几乎是不可预测的,而过滤器则可以帮助用户缩小搜索结果的范围,例如使用构面。


19
没错,如果用户正在执行Google类型搜索,那么我会使用查询吗?如果他们从下拉列表中选择可能的值(例如,发票计数> 50),那么这将是一个过滤器吗?
琼斯

4
是的,完全正确。每当您需要通过某种度量标准限制整个文档集时,通常都需要使用过滤器。因此,也许是按年龄,身长,身高等来决定的
Zach 2013年

我的解决方案在同一请求中使用过滤器和查询,并且在测试数据库上非常快。我们将很快在那里获取实时数据,以查看其实际速度。
琼斯

@Zach绝对清楚,在多租户系统中-拥有租户内用户的权限-听起来,租户/身份验证信息将是添加到每个查询的过滤器(即过滤查询)。对?
Scott Willeke

4
@activescott是的,这就是我要做的。您还可以设置过滤的别名,以便“用户别名”始终应用适当的过滤器。使管理更容易,并不需要更改代码更新查询,额外的克鲁夫特在您的查询,等等
扎克

99

这是官方文件说的:

通常,应使用过滤器代替查询:

  • 用于二进制是/否搜索
  • 用于查询精确值

通常,应使用查询代替过滤器:

  • 用于全文搜索
  • 结果取决于相关性分数

当我想删除文档时,如果可以的话,我应该使用过滤器吗?我不希望它被缓存
Rytek

删除文档时,您不需要任何分数,也不需要进行全文搜索。因此,这将是一个筛选器,因为您只需要做出删除/不删除决定。filter-query-context
nonNumericalFloat

13

一个例子(自己尝试)

说索引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(使用关键字filter

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

包含hellosam返回的文档。文件没有评分

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

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


11

除此以外,几乎没有其他产品。首先应用过滤器,然后对查询结果进行处理。为了存储每个文档的二进制真假匹配,使用了一个称为bitSet Array的东西。该BitSet数组在内存中,将从第二次查询过滤器开始使用。这样,使用位集数组数据结构,我们可以利用缓存的结果。

这里需要注意的一点是,仅在执行请求时才创建过滤器缓存,因此仅从第二次命中开始,我们实际上就获得了缓存的优势。

但是,您可以使用更暖和的API来解决这个问题。当您针对较暖的API使用过滤器注册查询时,只要有新查询,它将确保针对新细分执行查询。因此,我们将从第一次执行本身获得一致的速度。


1
有趣!我没有意识到过滤是在查询之前发生的。过滤器的缓存现在变得更有意义。
康斯坦·梅林,2015年

不总是。筛选分数查询和恒定分数查询之间的基本区别和主要区别。恒定分数总是先执行查询,然后对其应用过滤器。甚至过滤后的查询都具有可以在过滤器之前执行查询的设置。
piyushGoyal 2015年

10

基本上,当您要对带有评分的文档执行搜索时,将使用查询。过滤器用于缩小通过查询获得的结果集。过滤器是布尔值。

例如,假设您有一家餐厅索引,例如zomato。现在,您要搜索提供“比萨”的餐厅,这基本上就是您的搜索关键字。

因此,您将使用查询来查找所有包含“ pizza”的文档,并将获得一些结果。

现在说,您想要一家供应比萨饼且评分至少为4.0的餐厅清单。

因此,您需要做的就是在查询中使用关键字“ pizza”,然后将过滤器的评级应用为4.0。

发生的情况是通常将过滤器应用于通过查询索引获得的结果。


不能提供请求正文的示例吗?
2014年


0

从Elasticsearch版本2开始,过滤器和查询已合并,并且任何查询子句都可以用作过滤器或查询(取决于上下文)。与版本1一样,过滤器会缓存,如果计分无关紧要,则应使用过滤器。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.