ES(三)es查询语法

一、介绍:语法GET /索引/类型/_search         查询条件,这个查询条件有两种写法,

  一种是在GET的url中指定参数:这种方法比较简单,如查询所有

GET /wtyy-test/user/_search

   条件查询: 

GET /es-test/_search?q=blog

  分页查询:

GET /es-test/_search?size=5&from=10

还有一种是ES查询表达式 (DSL) 检索:将请求参数按照ES约定的格式构造为一个JSON进行请求,放在请求体中。下面重点来看下:

 1、查询条件:封装在query中,常用的查询方式有:

查询方式

含义

使用方法

备注

term过滤

term主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed 的字符串。

not_analyzed 的字符串:未经切词的文本数据类型。

  1. {

  2. "query": {

  3. "term": {

  4. "title": "内蒙古"

  5. }

  6. }

  7. }

 

terms过滤

terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么document需要一起去做匹配。

  1. {

  2. "query": {

  3. "terms": {

  4. "title": [

  5. "内蒙古",

  6. "黑龙江"

  7. ]

  8. }

  9. }

  10. }

 

range

range过滤允许我们按照指定范围查找一批数据。

  1. {

  2. "query":{

  3. "range": {

  4. "pubTime": {

  5. "gt": "2017-06-25",

  6. "lt": "2017-07-01"

  7. }

  8. }

  9. }

  10. }

范围操作符包含:

关键字

含义

gt

大于

gte

大于等于

lt

小于

lte

小于等于

exists和missing

exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件。

这两个过滤只是针对已经查出一批数据来,但是想区分出某个字段是否存在的时候使用。

  1. {

  2. "exists":{

  3. "field":"title"

  4. }

  5. }

 

bool过滤

bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:

must :: 多个查询条件的完全匹配,相当于 and。

must_not :: 多个查询条件的相反匹配,相当于 not。

should :: 至少有一个查询条件匹配, 相当于 or。

这些参数可以分别继承一个过滤条件或者一个过滤条件的数组

  1. {

  2. "bool":{

  3. "must":{

  4. "term":{

  5. "folder":"inbox"

  6. }

  7. },

  8. "must_not":{

  9. "term":{

  10. "tag":"spam"

  11. }

  12. },

  13. "should":[

  14. {

  15. "term":{

  16. "starred":true

  17. }

  18. },

  19. {

  20. "term":{

  21. "unread":true

  22. }

  23. }

  24. ]

  25. }

  26. }

2、排序:封装在sort中 。

二、DSL检索:

1、简单查询:

 1)查询所有结果:

GET /wtyy-test/user/_search
{
    "query":{"match_all":{}}
}

 2)条件查询:post_filter  和 query 的 区别 ,语法上没区别,唯一的在于 filter 不评分,所以 filter  比 query  快很多 ,filter 和query  可以共存。

GET /wtyy-test/user/_search
{
    "query":{
          "match":{
                    "name":"李四"
          }
    },
    "sort":[
        {
             "age":"desc"
       }
   ]
}

 3)范围查询:

GET /wtyy-test/user/_search
{
    "query":{
      "range": {
        "age": {
          "gte": 18,
          "lte": 20
        }
      }
    }
  
}

  4)指定查询结果的字段 _source

GET /wtyy-test/user/_search
{
    "query":{"match_all":{}},
    "_source":["name","age"]
}

5)多条件的复合查询bool : bool 里面的都是一些条件 ,must 必须瞒足,should 只要满足 minimum_should_match 个条件是ture ,filter只是过滤不计入评分。

GET /wtyy-test/user/_search
{
	"query": {
		"bool": {
			"must": [{
				"match": {
					"name": "李四"
				}
			}],
			"should": [{
					"match": {
						"age": 18
					}

				},
				{
					"match": {
						"address": "重庆"
					}

				}
			],
			"minimum_should_match": 1

		}
	}
}

查询结果:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 1.5162321,
    "hits": [
      {
        "_index": "wtyy-test",
        "_type": "user",
        "_id": "AXVuJKSiQnB0qZbmUT7E",
        "_score": 1.5162321,
        "_source": {
          "name": "李四",
          "age": 18
        }
      },
      {
        "_index": "wtyy-test",
        "_type": "user",
        "_id": "AXVuQymtQnB0qZbmUT7G",
        "_score": 1.5162321,
        "_source": {
          "name": "李四",
          "age": 18,
          "address": "上海"
        }
      },
      {
        "_index": "wtyy-test",
        "_type": "user",
        "_id": "AXVuBYO2QnB0qZbmUT69",
        "_score": 1.0324643,
        "_source": {
          "name": "李四",
          "age": 20,
          "address": "重庆"
        }
      }
    ]
  }
}

 2、分页查询:对于查询得到的结果,数目过多的情况下,es 默认会进行分页。分页主要有两个参数进行控制: size 显示应该返回的结果数量,默认是 10 ;from 显示应该跳过的初始结果数量,默认是 0。

GET /wtyy-test/user/_search
{
  "query":{
    "match": {
        "name": "李四"
    }
  },
  "size": 10,
  "from": 1
}

3、聚合函数:

1)求平均值:

GET  wtyy-test/user/_search
{
  "query": {
    "match": {"name":"李四"}
  },
  "aggs": {
    "total_count": {
      "value_count": {
        "field": "age"
      }
    },
    "pjz":{
      "avg": {
        "field": "age"
      }
    }
    
  }
  
}

  返回结果:

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 1.4252472,
    "hits": [
      {
        "_index": "wtyy-test",
        "_type": "user",
        "_id": "AXVuQymtQnB0qZbmUT7G",
        "_score": 1.4252472,
        "_source": {
          "name": "李四",
          "age": 18,
          "address": "上海"
        }
      },
      {
        "_index": "wtyy-test",
        "_type": "user",
        "_id": "AXVuJKSiQnB0qZbmUT7E",
        "_score": 1.0754046,
        "_source": {
          "name": "李四",
          "age": 18
        }
      },
      {
        "_index": "wtyy-test",
        "_type": "user",
        "_id": "AXVuBYO2QnB0qZbmUT69",
        "_score": 0.51623213,
        "_source": {
          "name": "李四",
          "age": 20,
          "address": "重庆"
        }
      }
    ]
  },
  "aggregations": {
    "pjz": {
      "value": 18.666666666666668
    },
    "total_count": {
      "value": 3
    }
  }
}

  4、分组:

GET  wtyy-test/user/_search
{
  "query": {
    "match": {"name":"李四"}
  },
  "aggs": {
    "fz": {
      "terms": {
        "field": "age"
      }
    }
  }
  
}

5、 scoll 游标查询,指定 scroll=时间 ,指定保存的分钟数,第一次发起请求放回的不是数据,而是 _scroll_id ,后面通过 _scroll_id 去请求数据,非常适合大批量查询。

get /user/student/_search?scroll=1m
{
    "query":{
      "match_all": {}
    },
    "size":2
  
}
GET /_search/scroll
{
    "scroll": "1m",
    "scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAIuFkRMbVZ0WFdvU1ZHWEJuelFIQk4tdFEAAAAAAAACLBZETG1WdFhXb1NWR1hCbnpRSEJOLXRRAAAAAAAAAi0WRExtVnRYV29TVkdYQm56UUhCTi10UQAAAAAAAAO1FlQwSkJqVng5UVpPUTIwbWw0a0NKV3cAAAAAAAADthZUMEpCalZ4OVFaT1EyMG1sNGtDSld3"
}

 游标 查询 是在 es 里面缓存了结果 ,然后一次 一次的去取 所以发起 第一次请求的时候只有 size ,没有from ,后面的 请求只有 scroll_id 和  scroll 时间

6、关键词高亮显示:

通常自己开发搜索引擎的时候,往往需要对搜索结果中的关键词高亮这种功能。请求体增加一个 highlight 属性,里面指明要高亮的字段。如下:

GET  wtyy-test/user/_search
{
  "query": {
    "match": {
      "address": "北京"
    }
  },
  "highlight": {
    "fields": {
      "address": {}
    }
  }
}

返回消息体如:

{
  "took": 61,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.7787034,
    "hits": [
      {
        "_index": "wtyy-test",
        "_type": "user",
        "_id": "1",
        "_score": 0.7787034,
        "_source": {
          "name": "王五1",
          "age": 1,
          "address": "湖北",
          "school": "测试学校"
        },
        "highlight": {
          "address": [
            "湖<em>北</em>"
          ]
        }
      }
    ]
  }
}

在返回体中有一个 highlight 字段,里面对 message 字段进行高亮处理: 关键词使用了 <em></em> 标签包围了。可以使用 css 修改对 <em> 标签的样式,以实现关键词高亮效果。

7、多索引查询:在多个索引中同时搜索文档,把多个索引看做一个使用。其实这也意味着,我们在存储的时候,没必要把所有的文档都存在一个 Index 中。 很常见的一个操作是,我们可以将文档按天分索引存储。例如: es-test-2020-03-11,es-test-2020-03-12 等, 在查询的时候,指定 es-test-* 查询即可,这样对外看来,文档似乎还是存储在一起,同时也减轻了 Index 的存储压力。(一个 ES 分片最多能存储 Integer.MAX_VALUE - 128 个文档)

GET /es-test-1,es-test-2/_search
GET /es-test-*/_search
GET /a*, b*/_search

8、批查询 api mget:

#批量查询
GET /_mget
{
  "docs":[
    {
      "_index":"user",
      "_type":"student",
      "_id":1
    },
    {
      "_index":"user",
      "_type":"student",
      "_id":2
    },
    {
      "_index":"user",
      "_type":"student",
      "_id":2
    }
  ]
}

 mget  如果请求url 里面有 index 和 type 后面 的 请求体里面就可以不写  index 和type

9、es的 并发处理 ,使用的乐观锁 在 后面加上 version:

POST  /user/student/1?version=3
{
  "name":"zyk",
  "age":0
}

 只有version = 当前记录的version的时候才能修改成功。es 可以自动控制 vserion 通过 ,version_type指定 ,version_type=external 要求 version 大于当前的version ,version_type=internal 这个是默认值 ,必须等于当前的值<br>version_type=external_gte 大于等于当前的version<br>version_type=force 已经废弃了不能用了,我也不知道以前什么意思,提升, Validation Failed: 1: version type [force] may no longer be used

POST  /user/student/1?version_type=external&version=505
{
  "name":"zyk",
  "age":0
}

三、动态映射

有一点值得注意的是,本文中的例子都是用了 message 字段来进行 match 搜索,如果换成字段名换成了其他,例如 content 可能就不行。这是因为在我这边的 ES 有一个默认的动态映射,将长度低于 2048 的字符串认定为 keyword 类型。但是字段名是 message 的话,则为 text 类型。keyword 类型不进行分词处理,不适合进行关键词搜索处理。这样就需要我们不得不关注 ES 的动态映射。此部分内容以后会再单独分一篇文章讲解。

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值