Elasticsearch学习笔记之查询表达式
一、前言:
Elasticsearch的查询分为两种一种是通过设置get请求的参数实现,一种是利用post传递查询表达式。
查询表达式(Query DSL)是一种非常灵活又富有表现力的查询语言。 Elasticsearch使用简单的 JSON 接口来展现 Lucene 功能的绝大部分。在你的应用中,你应该用它来编写你的查询语句。它可以使你的查询语句更灵活、更精确、易读和易调试。
二、查询语句的结构
查询表达式,只需将查询语句传递给 query 参数:
POST /_search
{
"query": YOUR_QUERY_HERE
}
ps:查询表达式需要使用post方法请求_search路径。或者使用/{index}/{type}/_search。可以对应索引下对应类型进行查询。
2.1 查询:
2.1.1 空查询(empty search)
在功能上等价于使用 match_all 查询, 正如其名字一样,匹配所有文档:
空查询
{}
match_all查询
POST /_search
{
"query": {
"match_all": {}
}
}
空查询可以指定from和size进行分页查询
POST /_search
{
"from": 30,
"size": 10
}
2.1.2 查询的典型结构:
{
QUERY_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
完整结构如下:
{
"query":{
< "bool":{ >
"Query_Action":{
"Field_Name":{
"Argument":"Value"
}
},
"filter" : {
"Query_Action":{
"Field_Name":{
"Argument":"Value"
}
}
}
< } >
}
Query_Action: 我归类的方式有:
- 布尔查询:must,must_not,should等 类似SQL的and,or,! 等
- 匹配查询: match multi_match等 类似SQL的like
- 范围查询: range 类似SQL的大于,小于,等于等
- term查询: term 类似SQL的 “=”
- 正则查询: regex 这个就不说了
- exists和missing查询: 类似于SQL is null,is not null
查询语法总结:
- 最外层必须是query对象
- 复合查询条件要包含在bool对象中
- 过滤器里面也是各种查询动作(不知道filter里面能不能放bool查询)
- 布尔查询可以是数组结构,包含多个条件。
2.1.3 布尔查询
must查询
must查询是必要条件,无论must和should,must_not如何搭配必须满足must查询的条件。
POST /my_index/my_type/_search
{
"query": {
"bool": {
"must": { "match": { "title": "quick" }}
}
}
}
must_not查询
must_not查询不参与匹配,只是把匹配结果中符合条件的去除掉。
POST /my_index/my_type/_search
{
"query": {
"bool": {
"must": { "match": { "title": "quick" }},
"must_not": { "match": { "title": "lazy" }}
}
}
}
should查询
should查询不影响匹配结果,只是当符合条件时,文档会被认为更相关。除非是查询语句中只包含should条件,那么必须满足最少一个should条件。可以通过minimum_should_match属性来控制满足条件的个数。
POST /my_index/my_type/_search
{
"query": {
"bool": {
"should": [
{ "match": { "title": "brown" }},
{ "match": { "title": "fox" }},
{ "match": { "title": "dog" }}
],
"minimum_should_match": 2
}
}
}
2.1.4匹配查询
match查询:
match查询接受文本/数字/日期类型数据,然后进行分析后构建一次查询。
POST /_search
{
"query": {
"match" : {
"message" : "this is a test"
}
}
}
match查询本质上也是一种布尔查询,含义是查询文本被分析后构建成了一个布尔查询。operator属性可以用来控制构建的布尔查询语句的逻辑关系(or,and)。如果将operator设置为and,但是又想获得一些不完全匹配的结果,可以设置minimum_should_match属性。
POST /_search
{
"query": {
"match" : {
"message" : {
"query" : "this is a test",
"operator" : "and"
}
}
}
}
match_phrase查询
match_phrase查询对query进行分析(分词)后,创建一个短语查询。 match_phrase查询要求查询的term都存在,同时按照输入的顺序排列。 默认情况下,term之间必需是紧挨着才能被查询到。但是我们通过设置slop属性控制term之间的间隔。
ps: 中文utf-8编码,一个字算两个单位
POST /_search
{
"query": {
"match_phrase" : {
"message" : {
"query": "this is a test",
"slop" : 4
}
}
}
}
match_phrase_prefix查询
The match_phrase_prefix is the same as match_phrase, except that it allows for prefix matches on the last term in the text.
match_phrase_prefix基本上同match_phrase相同,除了它允许匹配最后一个term的前缀。不过这种匹配在中文语境下就和match_phrase区别不大了。
multi_match查询
就是一个query可以在多个域上进行查询。
POST /_search
{
"query": {
"multi_match" : {
"query": "this is a test",
"fields": [ "subject", "message" ]
}
}
}
还可以使用通配符
POST /_search
{
"query": {
"multi_match" : {
"query": "Will Smith",
"fields": [ "title", "*_name" ]
}
}
}
multi_match如果只是支持在多个域上面查询,那我们可以直接使用match然后在多个域上查就好了嘛。multi_match不一样的是支持上述的所有查询类型,如下表。
查询类型作用best_fields默认类型,在所有域上查询文档。但是使用最佳匹配的域作为_score。most_fields在所有域上查询文档,和best_fields不同的是最后的_score是所有域查询结果的平均分。cross_fields很复杂,简单说就是一个查询在被分词后,对分词的结果在多个域上查询,每个词只要在某个域上存在就可以。也就是跨域phrase在每个域上进行phrase查询,然后选择结果最高的_score作为这个查询结果的_scorephrase_prefix在每个域上进行phrase_prefix查询,然后最后查询结果的_score是所有域查询结果的平均分。
不匹配所有查询:
匹配所有查询的反转,不匹配所有文档,虽然我暂时没想到这个可以用来干什么。
GET /_search
{
"query": {
"match_none": {}
}
}
2.1.5 term查询
和匹配查询不同的就是,term查询对每个域都需要是完全相同的匹配。
term查询
POST _search
{
"query": {
"term" : { "user" : "Kimchy" }
}
}
上面的查询结果是在user域上是Kimchy的所有文档。
terms查询
匹配多个term查询结果
POST _search
{
"query": {
"terms" : { "user" : ["kimchy", "elasticsearch"]}
}
}
查询结果是user域上为kimchy或者elasticsearch的文档。
2.1.6 range查询
range查询要以range对象开始,接受以下参数:
参数含义gte大于等于gt大于lte小于等于lt小于
ps:只有string,number,date三种数据类型可以进行range查询
POST _search
{
"query": {
"range" : {
"age" : {
"gte" : 10,
"lte" : 20,
"boost" : 2.0
}
}
}
}
2.1.7 exists查询和missing查询
POST /_search
{
"query": {
"exists" : { "field" : "user" }
}
}
exists查询用来判断某个域是否有值,具体来说:
{ "user": "jane" }
{ "user": "" }
{ "user": "-" }
{ "user": ["jane"] }
{ "user": ["jane", null ] }
以上都判断有值
{ "user": null }
{ "user": [] }
{ "user": [null] }
{ "foo": "bar" }
以上都默认无值
POST /_search
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "user"
}
}
}
}
}
missing查询就是exists查询的否定了~
三、总结:
Elasticsearch的查询表达式是非常重要必须要掌握的知识,但是总的来说比较复杂,这篇笔记把主要的部分归纳总结。后面会逐渐完善更多的知识。
Reference: