Elasticsearch查询
前端之家收集整理的这篇文章主要介绍了
Elasticsearch查询,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Query DSL
Elasticsearch提供了一个基于JSON的完整的查询DSL(领域特定语言)。它定义的查询语言由两种类型的子句组成:“叶子查询子句”和“组合查询子句”。
叶子查询子句
叶子查询子句查找特定字段中的特定值,例如 match、term 或 range 查询。
复合查询子句
复合查询子句包装其他叶子或复合查询,并用于以逻辑方式组合多个查询(如 bool 或 dis_max 查询),或更改其行为(如 constant_score 查询)。
1. Query and filter context
查询子句的行为取决于它是用在查询上下文(query context)还是用在过滤器上下文(filter context):
1.1. Query context
在查询上下文中的查询子句回答了“这个文档与这个查询子句的匹配程度是怎样的?”问题。除了决定文档是否匹配以外,查询子句还会计算一个“_score”,它表示文档与其他文档的相关程度。
1.2. Filter context
在过滤器上下文中,一个查询子句回答了“这个文档与查询子句匹配吗?”的问题。这个答案是简单的Yes或者No,也不会计算分数。过滤上下文主要用于过滤结构化数据,例如:
- 这个timestamp在2015年到2016年的范围内吗?
- 这个status字段的值是“published”吗?
(
PS:Query VS Filter
- 查询反应的是文档与查询子句的匹配程度,而过滤反应的是文档是否匹配查询子句
- 一个是筛选是否满足条件,情况无非两种:是或不是;一个是看满足条件的记录与查询条件的匹配程度
- 哪些满足条件,这是过滤;满足条件的这些记录与条件的匹配程度,这是查询
- 过滤不会计算评分,查询会计算评分
)
频繁使用的过滤器将被Elasticsearch自动缓存,以提高性能。
当查询子句中被传递了一个filter参数时过滤器上下文就生效了。例如,bool查询中的filter参数或者must_not参数。
下面是一个查询子句的例子,这个查询将匹配满足以下所有条件的文档:
- title 字段包含单词“search”
- content 字段包含单词“elasticsearch”
- status 字段包含明确的单词“published”
- publish_date 字段的包含的日期大于或等于2015-01-01
@H_
301_148@
curl -X GET @H_403_150@"@H_403_150@localhost:9200/_search@H_403_150@" -H @H_403_150@'@H_403_150@Content-Type: application/json@H_403_150@' -d@H_403_150@'
{
@H_403_150@query@H_403_150@": {
@H_403_150@bool@H_403_150@: {
@H_403_150@must@H_403_150@: [
{ @H_403_150@match@H_403_150@": { @H_403_150@title@H_403_150@": @H_403_150@Search@H_403_150@ }},{ @H_403_150@content@H_403_150@": @H_403_150@Elasticsearch@H_403_150@ }}
],@H_403_150@filter@H_403_150@: [
{ @H_403_150@term@H_403_150@": { @H_403_150@status@H_403_150@published@H_403_150@ }},1)">range@H_403_150@publish_date@H_403_150@gte@H_403_150@2015-01-01@H_403_150@ }}}
]
}
}
}
@H_403_150@'
关于上面的查询子句作如下说明:
- quary 参数表示这是一个查询上下文
- bool 和 两个match子句用在查询上下文中,表明它们参与每条文档的打分
- filter 参数表明这是过滤器上下文
- term 和 range 子句用在过滤器上下文中,它们会过滤掉不匹配的文档,而且不会影响匹配文档的分数
(PS:类比sql的话,match相当于模糊查询,term相当于精确查询,range相当于范围查询)
2. Match All Query
最简单的查询,匹配所有文档,使它们的_score为1.0
@H_
301_148@
curl -X GET @H_403_150@: {
@H_403_150@match_all@H_403_150@: {}
}
}
@H_403_150@'
_score可以被改变,通过用boost参数
@H_
301_148@
curl -X GET @H_403_150@boost@H_403_150@" : @H_403_150@1.2 }
}
}
@H_403_150@'
与match_all相反的是match_none,它不匹配任何文档
@H_
301_148@
curl -X GET @H_403_150@match_none@H_403_150@'
3. Full text queries
3.1. Match Query
match查询接受文本/数值/日期类型的数据,分析它们,并构造一个查询。
match是一种布尔类型的查询。这意味着它对提供的文本进行分析,并在分析的过程中为提供的文本构造一个布尔查询。operator 选项可以设置为 or 或者 and 以此来控制布尔子句(默认是 or )。例如:
@H_
301_148@
curl -X GET @H_403_150@ : {
@H_403_150@message@H_403_150@this is a test@H_403_150@
}
}
}
@H_403_150@'
注意,查询语句都是以“query”开头的,这里“message”是字段名
你也可以加一些参数,比如:
@H_
301_148@
curl -X GET @H_403_150@ : {
@H_403_150@,1)">operator@H_403_150@and@H_403_150@
}
}
}
}
@H_403_150@'
(PS:match是模糊查询)
3.2. Match Phrase Query
match_phrase 查询与 match类似,但是它是用于精确匹配或单词接近匹配的。例如:
@H_
301_148@
curl -X GET @H_403_150@match_phrase@H_403_150@'
当然,你也可以加参数
@H_301_148@
curl -X GET @H_403_150@analyzer@H_403_150@my_analyzer@H_403_150@'
这里“analyzer”是用来设置用那个分析器来分析文本
3.3. Match Phrase Prefix Query
类似于match_phrase查询,但是对最后一个单词进行通配符搜索。
match_phrase_prefix允许文本的最后一个单词进行前缀匹配
@H_301_148@
curl -X GET @H_403_150@match_phrase_prefix@H_403_150@quick brown f@H_403_150@'
除了match_phrase允许的那些参数外,match_phrase_prefix还可以接受一个max_expansions参数,它是用来控制最后一个单词可以扩展多少后缀(默认50)。
@H_301_148@
curl -X GET @H_403_150@max_expansions@H_403_150@10'
3.4. Multi Match Query
multi_match 相当于 match 的多字段版本
顾名思义,multi_match可以指定多个字段,而match只能针对一个字段
@H_301_148@
curl -X GET @H_403_150@{
@H_403_150@: {
@H_403_150@multi_match@H_403_150@ : {
@H_403_150@": @H_403_150@fields@H_403_150@": [ @H_403_150@subject@H_403_150@",@H_403_150@ ]
}
}
}
@H_403_150@'
另外,字段可以用通配符,例如下面的例子中可以查询 title , first_name , last_name 等字段:
@H_301_148@
curl -X GET @H_403_150@Will Smith@H_403_150@*_name@H_403_150@'
单个字段可以被提升,例如:
@H_301_148@
curl -X GET @H_403_150@" : [ @H_403_150@subject^3@H_403_150@'
上面的例子,subject字段的重要性是message字段的三倍
3.5. Query String Query
支持Lucene查询字符串语法,允许指定 AND | OR | NOT ,并且在单个查询字符串中进行多字段查询
@H_301_148@
curl -X GET @H_403_150@query_string@H_403_150@default_field@H_403_150@this AND that OR thus@H_403_150@'
query_string查询解析输入并围绕操作符拆分文本,每个文本部分都是独立分析的,例如:
@H_301_148@
curl -X GET @H_403_150@(new york city) OR (big apple)@H_403_150@'
上面的例子中,将被拆分成 “new york city” 和 “big apple” 两部分,并且每一部分都被分析器独立分析
注意,按操作符拆分
query_string的参数包括:
query 实例被解析的查询文本
default_field 如果没有指定前缀字段的话,这是默认的查询字段。(默认查询所有字段)
default_operator 如果没有明确指定操作符的话,那么这是默认的操作符。例如,如果默认操作符是OR的话,那么“my name is jack”将被翻译成“my OR name OR is OR jack”,同理,如果是AND,则被翻译成“my AND name AND is AND jack”
analyzer 用来解析查询字符串的解析器的名字
allow_leading_wildcard 如果设置了,那么 * 或 ? 允许作为第一个字符。默认是true
lenient 如果设置为true,则格式失败将被忽略
在query_string中,多字段查询应该这样写:
@H_301_148@
curl -X GET @H_403_150@" : [@H_403_150@name@H_403_150@],1)">this AND that@H_403_150@'
等价于
@H_301_148@
curl -X GET @H_403_150@: {
@H_403_150@(content:this OR name:this) AND (content:that OR name:that)@H_403_150@'
上面两个是等价的
3.6. Simple Query String Query
simple_query_string 是query_string的一个更简单、更健壮、更适合面向用户的版本
使用SimpleQueryParser解析上下文的查询。与常规的query_string查询不同,simple_query_string查询永远不会抛出异常,并丢弃查询的无效部分。
@H_301_148@
curl -X GET @H_403_150@simple_query_string@H_403_150@ : {
@H_403_150@\"fried eggs\" +(eggplant | potato) -frittata@H_403_150@": [@H_403_150@title^5@H_403_150@body@H_403_150@default_operator@H_403_150@
}
}
}
@H_403_150@'

3.7. 实例练习
准备数据

@H_301_148@
// 删除索引
curl -X DELETE @H_403_150@192.168.1.134:9200/book@H_403_150@"
创建索引
curl -X PUT @H_403_150@settings@H_403_150@number_of_shards@H_403_150@1
},1)">mappings@H_403_150@_doc@H_403_150@properties@H_403_150@": { @H_403_150@type@H_403_150@text@H_403_150@ },1)">author@H_403_150@": { @H_403_150@introduction@H_403_150@: {
@H_403_150@date@H_403_150@format@H_403_150@yyyy-MM-dd@H_403_150@
}
}
}
}
}
@H_403_150@'
查看索引
curl -X GET @H_403_150@192.168.1.134:9200/book?pretty@H_403_150@ 插入文档
curl -X PUT @H_403_150@192.168.1.134:9200/book/_doc/1@H_403_150@Hello Java@H_403_150@zhangsan@H_403_150@2008-11-15@H_403_150@This is a book for novice.@H_403_150@
}
@H_403_150@ 查看文档
curl -X GET @H_403_150@192.168.1.134:9200/book/_search?pretty@H_403_150@'

match查询(注意,match查询只能是针对单个字段)

这个例子中,我们用“Java”查询到2条,接下来用“Java入门”将查到5条

这是因为解析器会将“Java入门”拆分为“Java”和“入门”两个单词,而且默认的操作符是or
也就是说,查询的结果是title中包含“Java”或者“入门”的记录

现在变成查询title中同时包含“Java”和“入门”的记录,因此只有1条
multi_match多字段查询


match_phrase查询


对比不难发现,同样的关键字“Java从”,用match查出5条,用match_phrase只查出1条

query_string查询



4. Term level queries(单词级别查询)
全文本查询会在执行之前对查询字符串进行分析,而单词级别查询会对存储在反向索引中的精确的term进行操作。
这些查询通常用于结构化的数据,比如:numbers , dates ,enums 等,而不是对全文本字段。
(PS:也就是说,全文本查询之前要先对文本内容进行分词,而单词级别的查询直接在相应字段的反向索引中精确查找,单词级别的查询一般用于数值、日期等类型的字段上)
4.1. Term Query
在指定的字段中查找包含指定的精确的term的文档
term查询将在反向索引@H_403_150@(或者叫倒排索引)中查找包含特定的精确的term的文档。例如:
@H_301_148@
curl -X POST @H_403_150@" : { @H_403_150@user@H_403_150@Kimchy@H_403_150@ }
}
}
@H_403_150@'
上面的例子,在user字段的反向索引中查找包含精确的Kimchy的文档
还可以指定一个boost参数,使这个term查询比另一个查询具有更高的相关性得分。例如:
@H_301_148@
curl -X GET @H_403_150@should@H_403_150@: [
{
@H_403_150@: {
@H_403_150@: {
@H_403_150@value@H_403_150@urgent@H_403_150@2.0
}
}
},{
@H_403_150@normal@H_403_150@
}
}
]
}
}
}
@H_403_150@'
这个例子中,urgent查询子句有一个boost参数值为2.0,这就意味着它的重要程度是后面的normal查询子句的两倍,normal子句默认的boost是1.0
4.2. Terms Query
查找包含指定字段中指定的任何确切term的文档
筛选出与所提供的terms中任何一个匹配的文档
@H_301_148@
curl -X GET @H_403_150@terms@H_403_150@kimchy@H_403_150@elasticsearch@H_403_150@]}
}
}
@H_403_150@4.3. Range Query
查找指定字段在指定范围内包含值(日期、数字或字符串)的文档。
下面的例子返回age字段的值在10到20之间的文档:
@H_301_148@
curl -X GET @H_403_150@age@H_403_150@lte@H_403_150@20'
range查询可以接受下列参数:
gte 大于或等于
gt 大于
lte 小于或等于
lt 小于
boost 设置boost值,默认是1.0
4.3.1. Range on date fields
当range查询用于date类型的字段时,范围可以用Date Math表示:
@H_301_148@
curl -X GET @H_403_150@now-1d/d@H_403_150@lt@H_403_150@" : @H_403_150@now/d@H_403_150@'
当使用Date Math将日期四舍五入到最近的日期、月份、小时等时,四舍五入日期取决于范围的两端是包含的还是排除的。
例如:
rounded up 向上舍入
rounded down 向下舍入
gt 大于2014-11-18||/M 变成 2014-11-30T23:59:59.999
gte 大于或等于2014-11-18||/M 变成 2014-11-01
lt 小于2014-11-18||/M 变成 2014-11-01
lte 小于或等于2014-11-18||/M 变成2014-11-30T23:59:59.999
这个其实很好理解,
大于2014-11-18||/M相当于是大于2014年11月,因此大于2014-11-18||/M等价于大于2014-11-30 23:59:59
也就是说,大于11月,相当于是大于11月的最后一天,即11-30 23:59:59
同理,大于或等于2014-11-18||/M,相当于大于或等于11月,自然是11月的第一天,即2014-11-01
同理,小于2014-11-18||/M,相当于小于11月,自然是小于11月1日,故而小于2014-11-18||/M等价于小于2014-11-01
同理,小于或等于2014-11-18||/M,等于11月自然是包含11月的,意味着小于11月30日,故而小于或等于2014-11-18||/M等价于小于或等于2014-11-30 23:59:59
4.3.2. Date format in range query
在日期范围查询的时候,我们可以指定日期格式。例如:
@H_301_148@
curl -X GET @H_403_150@born@H_403_150@01/01/2012@H_403_150@2013@H_403_150@dd/MM/yyyy||yyyy@H_403_150@'
这个例子是查询在2012-01-01到2013-12-31之间出生的人
下面看时间范围查询
@H_301_148@
curl -X GET @H_403_150@timestamp@H_403_150@2015-01-01 00:00:00@H_403_150@now@H_403_150@time_zone@H_403_150@+01:00@H_403_150@4.4. Exsit Query
在特定的字段中查找非空值的文档
@H_301_148@
curl -X GET @H_403_150@exists@H_403_150@field@H_403_150@4.5. Prefix Query
查找包含带有指定前缀的term的文档
@H_301_148@
curl -X GET @H_403_150@'
{ @H_403_150@prefix@H_403_150@ki@H_403_150@ }
}
}
@H_403_150@'
可以关联boost
@H_301_148@
curl -X GET @H_403_150@" : { @H_403_150@ } }
}
}
@H_403_150@4.6. Wildcard Query
支持通配符查询,*表示任意字符,?表示任意单个字符
@H_301_148@
curl -X GET @H_403_150@wildcard@H_403_150@ki*y@H_403_150@'
可以加boost参数
@H_301_148@
curl -X GET @H_403_150@ } }
}
}
@H_403_150@4.7. Regexp Query
正则表达式查询
@H_301_148@
curl -X GET @H_403_150@regexp@H_403_150@:{
@H_403_150@name.first@H_403_150@s.*y@H_403_150@4.8. Ids Query
用_uid字段查询
@H_301_148@
curl -X GET @H_403_150@ids@H_403_150@values@H_403_150@1@H_403_150@4@H_403_150@100@H_403_150@]
}
}
}
@H_403_150@4.9. 实例练习







5. 复合查询
复合查询包装其他复合查询或叶子查询,以组合它们的结果和得分,更改它们的行为,或从查询切换到筛选上下文。
5.1. 固定分数查询
@H_301_148@
curl -X GET @H_403_150@constant_score@H_403_150@}
},1)">'
5.2. 布尔查询

关于should子句,特别要注意:
如果这个布尔查询位于查询上下文,并且有must或者filter子句,那么即使should子句没有匹配任何文档,也没关系
如果是位于过滤器上下文,或者既没有must也没有filter,那么至少有一个should查询必须匹配文档。
这个行为可以通过设置minimum_should_match参数来显式地控制。
举个例子:

@H_301_148@
curl -X POST @H_403_150@ }
},1)">: {
@H_403_150@tag@H_403_150@tech@H_403_150@must_not@H_403_150@ : {
@H_403_150@10,1)"> }
}
},1)"> : [
{ @H_403_150@wow@H_403_150@ } },1)"> } }
],1)">minimum_should_match@H_403_150@1.0'
查询user为“kimchy”,并且tag为“tech”,并且age不在10~20之间,并且tag为wow或elasticsearch的文档
filter查询分数默认是0
@H_301_148@
curl -X GET @H_403_150@: {
@H_403_150@: {
@H_403_150@active@H_403_150@
}
}
}
}
}
@H_403_150@5.3. 实例练习





参考
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html