其实准确来说,ES中的查询操作分为2种:查询(query)和过滤(filter)。查询即是之前提到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序。而过滤(filter)只会筛选出符合的文档,并不计算得分,且它可以缓存文档。所以,单从性能考虑,过滤比查询更快。
换句话说,过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时,应先使用过滤操作过滤数据,然后使用查询匹配数据。
过滤器使用
查询10月之前contents字段包含“ES”的文档
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
过滤查询包含filtered关键字,里面又包含普通的查询query逻辑和filter 过滤逻辑。运行时先执行过滤语句,后执行普通查询。对比下面只使用了查询的DSL:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
两者返回结果是一样的。
过滤器类型
过滤器类型与查询类型基本相对应,都有范围(过滤)查询、term、terms等类型。
term、terms过滤
term、terms的含义与查询时一致。term用于精确匹配、terms用于多词条匹配。不过既然过滤器既然适用于大氛围过滤,term、terms在过滤中使用意义不大。
举例见前面过滤器使用一节
范围过滤(range)
查询16年10月以来所有内容含有“java”的文档,先过滤剩下符合10月的文章,再精确匹配。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
exists、mising过滤器
exists过滤指定字段没有值的文档
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
将不返回id字段无值的文档。
missing 过滤器与exists相反,它过滤指定字段有值的文档。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
只返回缺少id值的文档,与上次exists过滤结果形成互补。
标识符(ids)过滤器
需要过滤出若干指定_id的文档,可使用标识符过滤器(ids)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
需注意的是:指定的标识符是文档的_id,为文档唯一标识。不同于自己指定的id字段。
限定过滤器(limit)
限定过滤器限定单个分片返回的文档数。
还记得 ElasticSearch笔记-基础知识文章最后提到的分页吗?如果你查询10条数据,则每个分片都会返回10条数据,集合后再选出前10条数据。如果使用limit限定过滤器,则可限定每个分片返回文档数。
限定每个分片返回一条数据
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
组合过滤器
可以对这些过滤器组合使用,ES中有2类组合过滤器。一类是bool过滤器,一类是and、or、not过滤器。bool过滤器对应布尔查询(bool),关于两者的区别,详细解释在这里:
关于elasticsearch filter bitset的全部
这里简要说一下:
- bool过滤器使用了bitset结构标识该文档是否匹配,当重复执行同一过滤时可简单查询bitset结构从而提高效率。应尽量使用bool过滤。
- 位置过滤(Geo filter)、数值范围过滤(Numeric_range filter)、脚本过滤(Script filter)没有bitset结构,使用and、or、not过滤器更高效。
总结来说,一般情况下用bool过滤器,当遇到位置查询、数值范围、脚本查询时使用and、or、not过滤。
查询日期在16年10月份且文章标题或内容包含“ES“的文档
用SQL表示为
- 1
使用bool过滤器
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
布尔查询也可嵌套布尔查询,如要查询16年10月份内容有关ES的文章或任何时段文章名称与java相关的所有文章。(这里只是举例,不考虑实际情况)
用SQL表示为
- 1
- 2
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
这里解释一下,我们查询的主要用or关系连接,所以使用bool查询的should语句。一边是contents like '%ES%' and date between '2016-10-01' and '2016-10-31' ,另一个为name like '%java%' 前者需嵌套一个bool查询,使用must连接,后者简单使用match即可。
注意这种结构的写法。类似可参考Elasticsearch权威指南-组合过滤
本文介绍了Elasticsearch中的查询(query)与过滤(filter)的区别及其应用场景。查询默认计算文档得分并排序,而过滤则筛选文档并不计算得分。文章还详细说明了如何使用过滤器进行高效数据筛选,并提供了多种过滤器类型的示例。
3661

被折叠的 条评论
为什么被折叠?



