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 的字符串:未经切词的文本数据类型。 |
|
|||||||||||
terms过滤 |
terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么document需要一起去做匹配。 |
|
|||||||||||
range |
range过滤允许我们按照指定范围查找一批数据。 |
|
范围操作符包含:
|
||||||||||
exists和missing |
exists 和 missing 过滤可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件。 这两个过滤只是针对已经查出一批数据来,但是想区分出某个字段是否存在的时候使用。 |
|
|||||||||||
bool过滤 |
bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符: must :: 多个查询条件的完全匹配,相当于 and。 must_not :: 多个查询条件的相反匹配,相当于 not。 should :: 至少有一个查询条件匹配, 相当于 or。 这些参数可以分别继承一个过滤条件或者一个过滤条件的数组 |
|
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 的动态映射。此部分内容以后会再单独分一篇文章讲解。
上一篇: ES查询-基本查询