Elasticsearch查询过滤解惑

database

简介

之前一直被查询(query)与过滤(filter)所困惑,为什么同样是bool在一个地方就是查询,在另一个地方就是过滤了。

后来仔细的看了一下官方文档才发现,都是查询,只是区分:

  1. query context(查询上下文)
  2. filter context(过滤上下文)

为什么要区分query context与filter context呢?

因为效率不同,在 filter context中的查询更加高效,因为filter context不会计算相关性评分,并且ES会自动缓存高频过滤查询。

哪些是过滤上下文

首先看到filter肯定是了,另外在bool查询中的must_not也会在filter context中执行。

filter

bool查询:

{

"query": {

"bool": {

"filter": [

{ "term": { "status": "1" }},

{ "range": { "create_date": { "lte": "2020-01-01" }}}

]

}

}

}

constant_score查询:

{

"query": {

"constant_score" : {

"filter" : {

"term" : { "user" : "tim"}

},

"boost" : 1.2

}

}

}

聚合函数中:

{

"aggs" : {

"month" : {

"filter" : { "term": { "type": "2" } }

}

}

}

must_not

{

"query": {

"bool" : {

"must_not" : {

"range" : {

"age" : { "gte" : 18, "lte" : 30 }

}

}

}

}

}

bool查询

类型

说明

must

表示条件必须满足,多个条件之间的关系是and,表示同时满足

should

表示至少匹配一个,多个条件之间的关系是or,表示至少满足一个

filter

条件必须满足,和must不同,filter在过滤上下文执行,不计算相关性得分

must_not

条件必须不满足,在过滤上下文执行,不计算相关性得分

注意:must_not是在filter context(过滤上下文执行)

{

"query": {

"bool" : {

"must" : {

"term" : { "status" : 1 }

},

"filter": {

"term" : { "type" : "Component" }

},

"must_not" : {

"range" : {

"ctime" : { "gte" : "2019-12-01", "lte" : "2020-01-01" }

}

},

"should" : [

{ "term" : { "tag" : "Kafka" } },

{ "term" : { "tag" : "Elasticsearch" } }

]

}

}

}

如上所示,term表示term查询,表示精确匹配,range查询是范围匹配。

上面的查询的含义是,文档中status字段必须为1,type字段必须是"Component",ctime字段必须在2019-12-01到2020-01-01这个范围之内,tag字段必须包含"Kafka"或者"Elasticsearch"。

全文搜索查询

match

match最常用,做的就是对应字段的全文索引。

{

"match" : {

"lauguage" : "Java"

}

}

{

"query": {

"match" : {

"message" : {

"query" : "java python ruby"

}

}

}

}

multi_match

multi_match和match差不多,但是可以指定多个字段搜索。

{

"query": {

"multi_match" : {

"query": "java python ruby",

"fields": [ "subject", "message" ]

}

}

}

match_all

match_all可以查询到所有索引字段,没有查询条件下的默认使用match_all。

{

"match_all" : {}

}

match_phrase

match_phrase和match有点相似,但是有2点很大区别:

  1. 查询分词的单词必须要在文档相应字段分词中全部出现
  2. 单词出现的顺序也必须一致

{

"query": {

"match_phrase" : {

"message" : "java python ruby"

}

}

}

出现相对位置可以使用slop参数调整

{

"query": {

"match_phrase": {

"message": {

"query": "java python ruby",

"slop": 2

}

}

}

}

可以参考下面的查询示例,下面是测试数据:

如上图所示,是没有slop参数的查询结果。

如上图所示,是slop参数为2的查询结果。

如上图所示,是slop参数为3的查询结果。

我们可以看到,slop参数就是调整查询单词中能间隔slop-1个单词。

match_phrase_prefix

match_phrase_prefix和match_phrase差不多,但是运行前缀匹配

{

"query": {

"match_phrase_prefix" : {

"message" : {

"query" : "java python r"

}

}

}

}

其他常用查询

出来我们上面介绍的bool查询、全文搜索查询以及涉及到的term、range等查询,我们还有一些其他常用的查询,下面我们就简单的介绍一下。

terms

前面我们已经有提到term查询,表示精确匹配,terms和term基本一样,但是terms允许设置多个值,只要有一个值精确匹配就算匹配成功。

{

"query" : {

"terms" : {

"component" : ["kafka", "elasticsearch"],

"boost" : 1.5

}

}

}

如上所示,表示只要component字段中精确匹配到kafka 或者 elasticsearch就算匹配成功。

boost影响文档相关性,大于1表示计算时增加文档相关性,小于1表示计算时减小文档相关性。

terms_set

terms_set查询是给定一个数组,如果文档中的对应字段包含至少指定个值在参数数组中就匹配。

听起来有点绕,没有关系,我们看一个示例,先创建一个user索引,然后添加2个文档如下。

PUT /user/_doc/1?refresh

{

"name": "tim",

"hobby": ["看书", "跑步"],

"required_matches": 2

}

PUT /user/_doc/2?refresh

{

"name": "allen",

"hobby": ["看书", "冥想"],

"required_matches": 2

}

下面我们就可以执行terms_set查询了。

GET /user/_search

{

"query": {

"terms_set": {

"hobby.keyword": {

"terms": ["看书", "游泳", "冥想"],

"minimum_should_match_field": "required_matches"

}

}

}

}

如上所示,查询中使用的是hobby.keyword,而不是hobby,是因为添加user映射的时候没有设置mapping,自动映射hobby为text类型,但是自动映射还使用了fields参数,所以我们可以使用hobby.keyword来搜索。

如果怕麻烦,可以直接设置一下mapping,把hobby设置为keyword类型。

上面的搜索会查询到name为allen的文档,如果我们把"冥想"换成"跑步"就会搜索到name为tim的文档。

感觉比较蛋疼的是最小匹配个数要在文档中设置,而不是直接在查询中设置值,在查询中使用的是引用文档中最小匹配的字段

exists

{

"query": {

"exists": {

"field": "gid"

}

}

}

ids

{

"query": {

"ids" : {

"values" : ["1", "3", "5", "7", "9"]

}

}

}

prefix

前缀匹配有时候非常有用,比如说我们要找老王:

{

"query": {

"prefix" : { "name" : "王" }

}

}

wildcard

如果觉得prefix前缀查询还不能满足你的需求,那还可以考虑通配符查询。

{

"query": {

"wildcard": {

"name": {

"value": "王*五",

"boost": 1.5

}

}

}

}

wildcard支持2个通配符:

  1. ?表示匹配一个字符
  2. *匹配0到多个字符

boost的值可以影响相关性,小于1表示减小文档的相关性,大于1表示增加文档的相关性。

如果通配符还不满足需求,那还可以考虑regexp正则表达式查询

但是,强烈推荐线上环境只使用prefix,如果要希望影响评分相关性,那使用wildcard也不要以通配符开头。

constant_score

用时候我们只想过滤,就可以考虑constant_score查询:

{

"query": {

"bool": {

"must": {

"match_all": {}

},

"filter": {

"term": {

"status": 1

}

}

}

}

}

等价于:

{

"query": {

"constant_score": {

"filter": {

"term": {

"status": 1

}

}

}

}

}

文档

查询与过滤上下文

结构化查询

bool查询

match

© 著作权归作者所有

打赏

点赞 (0)

收藏 (0)

分享

微博

QQ

微信

打印

举报

上一篇:

Elasticsearch常用查询过滤接口与值得注意的问题

下一篇:

Elasticsearch中mapping值得注意的一些小细节

trayvon

开源项目作者

作为一个开源项目作者,是时候站出来拯救世界了!

领取时间:2019/10/24

领取条件:开源项目被开源中国收录的开发者可领取

粉丝 19

博文 195

码字总数 284244

作品 1

程序员

关注

私信

提问

加载中

请先登录后再评论。

删除一条评论

评论删除后,数据将无法恢复

取消

确定

相关文章

最新文章

Nutch学习笔记4-Nutch 1.7 的 索引篇 ElasticSearch

上一篇讲解了爬取和分析的流程,很重要的收获就是: 解析过程中,会根据页面的ContentType获得一系列的注册解析器, 依次调用每个解析器,当其中一个解析成功后就返回,否则继续执行下一个解...

强子哥哥

2014/06/26

712

0

日志分析平台 - Kibana

Kibana 是一个为 Logstash 和 ElasticSearch 提供的日志分析的 Web 接口。可使用它对日志进行高效的搜索、可视化、分析等各种操作。 环境要求: ruby >= 1.8.7 (probably?) bundler logstash...

匿名

2013/02/13

11.7W

1

开源数据访问组件--Smark.Data

Smark.Data是基于Ado.net实现的数据访问组件,提供基于强类型的查询表达式进行灵活的数据查询,统计,修改和删除等操作;采用基于条件驱动的操作模式,使数据操作更简单轻松;内部通过标准SQL...

泥水佬

2013/03/12

2.6K

0

Amazing Audio Engine

Amazing Audio Engine 是基于 Core Audio 的远程 IO 系统用以提供低延迟的音频连接,通过内置的混音、过滤和生效。该框架支持大多数音频格式和比特率,同时提供音频输入、录制和监控功能。 ...

匿名

2013/03/21

1.2K

0

超快的css selector引擎--kquery 2.0

kquery是一款基于javascript完整实现css3选择器引擎. 兼容所有主流浏览器ie6+/chrome/firefox/opera/safari, 压缩和gzip之后仅8kb大小。智能编译引擎优化去除不必要的逻辑, 查询速度远胜于...

aaron.xiao

2012/10/23

730

0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

自制超声波驱狗器(第三版)

文档标识符:Ultrasonic_Dog_Repellent_II_T-D-P7 作者:DLHC 最后修改日期:2020.8.13 本文链接: https://www.cnblogs.com/DLHC-TECH/p/Ultrasonic_Dog_Repellent_II_T-D-P7.html “威力”......

osc_t4kk3au7

21分钟前

0

0

测试框架mocha入门

单元测试 今天带你了解下测试框架mocha,这是一个js的测试框架,而且适用于node和浏览器环境。通过它,我们可以为我们模块、组件级别以上的代码编写单元测试用例,保证代码输出质量。 一、安...

字节逆旅

昨天

0

0

ElasticSearch 7.8.1集群搭建

通往集群的大门 集群由什么用? 高可用   高可用(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。如果系统每运行100个时间...

osc_hwc3munb

22分钟前

13

0

如何面对人生危机?

点击蓝字关注,回复“职场进阶”获取职场进阶精品资料一份 一名读者提问:洋哥,我7年前从大厂出来,创业多年。连续失败,没买车也没房,女朋友也和我分手了,父母也对我失望至极。最近我开始...

张善友

今天

0

0

手写AOP实现过程

一.手写Aop前基础知识 1.aop是什么? 面向切面编程(AOP):是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP)。 在进行OOP开发时,都是基于对组件(比如类)进行开发...

osc_qyg23ccq

23分钟前

0

0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSCHINA 社区

关于我们

联系我们

合作伙伴

Open API

在线工具

码云 Gitee.com

企业研发管理

CopyCat-代码克隆检测

实用在线工具

微信公众号

OSCHINA APP

聚合全网技术文章,根据你的阅读喜好进行个性推荐

下载 APP

©OSCHINA(OSChina.NET)

工信部

开源软件推进联盟

指定官方社区

深圳市奥思网络科技有限公司版权所有

粤ICP备12009483号

顶部

以上是 Elasticsearch查询过滤解惑 的全部内容, 来源链接: utcz.com/z/535168.html

回到顶部