ES 中 DSL语句复习
- 获取es中的所有索引库
GET _cat/indices //所有索引库
- 向es中添加文档或者类型字段
PUT /suc/ass/1
{
"name":"颜淮川"
}
POST /suc/ass/1
{
"name":"颜淮川"
}
- es中的乐观锁 在执行了修改或者新增就会拥有seq_no的乐观锁
PUT /school/student/1?if_seq_no=4&if_primary_term=1
{
"name":"张三",
"age":30
}
- es中查询单个文档
GET /suc/saa/1
- 更新es中的文档
POST /schools/student/1
{
"name":"ford"
}
PUT /schools/student/1
{
"name":"ford"
}
// 问题:如果该文档有三个字段,那么他会更新所有的文档,也就是说这个类型中字段一旦更新只有name这一个属性,他是一个全改的操作
POST /schools/student/1/_update
{
"doc":
{
"name":"ford"
}
}
// 这样的话在指定类型的文档中只修改name属性
- es中删除文档的操作
// 注意:es中的文档的修改本质上是一种逻辑删除
delete /索引名/类型/_id
// 删除索引库
delete /schools
- 查看索引库中字段的类型
GET /school/_mapping
// 创建映射字段的语法
PUT /索引库名/_mapping {
"properties": {
"字段名": {
"type": "类型",
"analyzer": "分词器"
}
}
}
// 设置字段的类型
type: 可以是text、keyword、long、short、date、integer、boolean、object
index : 是否索引查询
analyzer: 提供给text类型指定分词器
// 其中注意事项
index:false // 表示不索引查询 要是查询的话报错
vo_value:false // 是正排索引
例:
PUT /goods-info
{
"mappings": {
"properties": {
"skuId": {
"type": "long"
},
"spuId": {
"type": "long"
},
"skuTitle": {
"type": "text",
"analyzer": "ik_max_word"
},
"skuPrice": {
"type": "keyword"
},
"skuImg": {
"type": "keyword",
"index": false
},
"saleCount": {
"type": "long"
},
"hotScore": {
"type": "long"
},
"brandId": {
"type": "long"
},
"brandName": {
"type": "keyword"
},
"brandImg": {
"type": "keyword",
"index": false,
"doc_values": false
},
"categoryName": {
"type": "keyword"
},
"hasStock": {
"type": "boolean"
},
"attrList": {
"type": "nested",
"properties": {
"attrId": {
"type": "long"
},
"skuId": {
"type": "long"
},
"attrName": {
"type": "keyword",
"ignore_above" : 256
},
"attrValue": {
"type": "keyword",
"ignore_above" : 256
}
}
}
}
}
}
(重点) DSL语句查询
-
普通查询:
// match全文索引查询 GET /company-index/_search { "query": { "match": { "job": "Java软件工程师" } } } // match_phrase短语查询不用分词 GET /company-index/_search { "query": { "match_phrase": { "job": "Java软件工程师" } } } // multi_match 组成查询 GET /company-index/_search { "query": { "multi_match": { "query":"李四" "fields": ["需要查询的属性1","需要查询的属性1"] } } }
-
bool复合查询
must // 文档必须匹配这些条件才能查询出来
must_not // 文档必须不匹配这些条件才能查询出来
should // 如果文档满足了should内的条件,为该文档增加_score 否则无影响
filter // 使用过滤模式进行查询
term // 精确查询全文索引使用match** ,分text的偏keyword类型使用term
GET /company-index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"job": "软件工程师"
}
}
],
"must_not": [
{"match": {
"name": "李四"
}}
],
"should": [
{"range": {
"payment": {
"gte": 9000,
"lte": 20000
}
}}
],
"filter": {
"term":{
"_id":1
}
}
}
}
}
分页查询数据,每页显示10条记录
我们可以假设在一个有5个主分片的索引中搜索。 当我们请求结果的第一页,每一个分片产生前 10 的结果,并且返回给 协调节点。协调节点对50个结果排序得到全部结果的前10个。
现在假设我们请求第1000页,从 10001 到 10010 。所有都以相同的方式工作除了每个分片不得不产生前10010个结果。然后协调节点对全部50050个结果排序最后丢弃掉这些结果中的 50040 个结果。
可以看到,在分布式系统中,对结果排序的成本随分页的深度成指数上升。
// 基本分页查询,但是会有深度问题 10000 页到10010 页 在多个(5)分片上 拼接起来就是50050 数据页量太大 深度问题,
// 基本分页使用优先与深度不多才使用
GET /students/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "scott"
}
}
]
}
},
"from": 0,
"size": 10
}
滚动scroll分页
第一次请求传入size条数, 按照_doc排序。请求地址上scroll=1m 表示此次查询的会话是一分钟,并且在这一分钟内不会查询到向ES中添加的新的数据。
GET /company-index/_search?scroll=1m
{
"query": {
"match_all": {}
},
"sort": [
{
"_doc": {
"order": "desc"
}
}
],
"size": 2
}
scroll每个批次查询的条数是: size * number_of_primary_shards
缺点: 数据并不是实时的。
nested数组查询
// 基本条件必须是nested类型
// 查询方式 从query下找到nested 内部再嵌套一个bool方法
// 类似于套娃
GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
}
}
Bucket聚合查询
// 普通的nested查询
GET /goods-info/_search
{
"size": 0,
"aggs": {
"per_count": {
"terms": {
"size":100,
"field": "brandId",
"min_doc_count":1
}
}
}
}
// 内部nested查询
GET /goods-info/_search
{
"size": 1,
"aggs": {
"personList": {
"nested": {
"path": "attrList"
},
"aggs": {
"aggsList": {
"terms": {
"field": "attrList.attrName",
"size": 10
}
}
}
}
}
}
金额区间查询
{
"query": {
"range": {
"reply": {
"gte": 245,
"lte": 250
}
}
}
}
gt:大于,gte:大于等于,lt:小于,lte:小于等于
日期区间查询
{
"query": {
"range": {
"postdate": {
"gte": "2016-09-01 00:00:00",
"lte": "2016-09-30 23:59:59",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
查询非空字段
返回对应字段中至少有一个非空值的文档,也就是说,该字段有值
{
"query": {
"exists": {
"field": "user"
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0oOlfDCH-1640421838587)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20211215234857174.png)]
查询多个id的值
GET /goods-info/_search
{
"query": {
"ids": {
"values": [1,2,3]
}
}
}
多个nested查询
{
"query": {
"bool": {
"must": [
{"nested": {
"path": "user",
"query": {
"term": {
"user.first": {
"value": "Li"
}
}
}
}},
{
"nested": {
"path": "user",
"query": {
"term": {
"user.last": {
"value": "Wang"
}
}
}
}
}
]
}
}
}
ES 中 DSL语句复习
- 获取es中的所有索引库
GET _cat/indices //所有索引库
- 向es中添加文档或者类型字段
PUT /suc/ass/1
{
"name":"颜淮川"
}
POST /suc/ass/1
{
"name":"颜淮川"
}
- es中的乐观锁 在执行了修改或者新增就会拥有seq_no的乐观锁
PUT /school/student/1?if_seq_no=4&if_primary_term=1
{
"name":"张三",
"age":30
}
- es中查询单个文档
GET /suc/saa/1
- 更新es中的文档
POST /schools/student/1
{
"name":"ford"
}
PUT /schools/student/1
{
"name":"ford"
}
// 问题:如果该文档有三个字段,那么他会更新所有的文档,也就是说这个类型中字段一旦更新只有name这一个属性,他是一个全改的操作
POST /schools/student/1/_update
{
"doc":
{
"name":"ford"
}
}
// 这样的话在指定类型的文档中只修改name属性
- es中删除文档的操作
// 注意:es中的文档的修改本质上是一种逻辑删除
delete /索引名/类型/_id
// 删除索引库
delete /schools
- 查看索引库中字段的类型
GET /school/_mapping
// 创建映射字段的语法
PUT /索引库名/_mapping {
"properties": {
"字段名": {
"type": "类型",
"analyzer": "分词器"
}
}
}
// 设置字段的类型
type: 可以是text、keyword、long、short、date、integer、boolean、object
index : 是否索引查询
analyzer: 提供给text类型指定分词器
// 其中注意事项
index:false // 表示不索引查询 要是查询的话报错
vo_value:false // 是正排索引
例:
PUT /goods-info
{
"mappings": {
"properties": {
"skuId": {
"type": "long"
},
"spuId": {
"type": "long"
},
"skuTitle": {
"type": "text",
"analyzer": "ik_max_word"
},
"skuPrice": {
"type": "keyword"
},
"skuImg": {
"type": "keyword",
"index": false
},
"saleCount": {
"type": "long"
},
"hotScore": {
"type": "long"
},
"brandId": {
"type": "long"
},
"brandName": {
"type": "keyword"
},
"brandImg": {
"type": "keyword",
"index": false,
"doc_values": false
},
"categoryName": {
"type": "keyword"
},
"hasStock": {
"type": "boolean"
},
"attrList": {
"type": "nested",
"properties": {
"attrId": {
"type": "long"
},
"skuId": {
"type": "long"
},
"attrName": {
"type": "keyword",
"ignore_above" : 256
},
"attrValue": {
"type": "keyword",
"ignore_above" : 256
}
}
}
}
}
}
(重点) DSL语句查询
-
普通查询:
// match全文索引查询 GET /company-index/_search { "query": { "match": { "job": "Java软件工程师" } } } // match_phrase短语查询不用分词 GET /company-index/_search { "query": { "match_phrase": { "job": "Java软件工程师" } } } // multi_match 组成查询 GET /company-index/_search { "query": { "multi_match": { "query":"李四" "fields": ["需要查询的属性1","需要查询的属性1"] } } }
-
bool复合查询
must // 文档必须匹配这些条件才能查询出来
must_not // 文档必须不匹配这些条件才能查询出来
should // 如果文档满足了should内的条件,为该文档增加_score 否则无影响
filter // 使用过滤模式进行查询
term // 精确查询全文索引使用match** ,分text的偏keyword类型使用term
GET /company-index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"job": "软件工程师"
}
}
],
"must_not": [
{"match": {
"name": "李四"
}}
],
"should": [
{"range": {
"payment": {
"gte": 9000,
"lte": 20000
}
}}
],
"filter": {
"term":{
"_id":1
}
}
}
}
}
分页查询数据,每页显示10条记录
我们可以假设在一个有5个主分片的索引中搜索。 当我们请求结果的第一页,每一个分片产生前 10 的结果,并且返回给 协调节点。协调节点对50个结果排序得到全部结果的前10个。
现在假设我们请求第1000页,从 10001 到 10010 。所有都以相同的方式工作除了每个分片不得不产生前10010个结果。然后协调节点对全部50050个结果排序最后丢弃掉这些结果中的 50040 个结果。
可以看到,在分布式系统中,对结果排序的成本随分页的深度成指数上升。
// 基本分页查询,但是会有深度问题 10000 页到10010 页 在多个(5)分片上 拼接起来就是50050 数据页量太大 深度问题,
// 基本分页使用优先与深度不多才使用
GET /students/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "scott"
}
}
]
}
},
"from": 0,
"size": 10
}
滚动scroll分页
第一次请求传入size条数, 按照_doc排序。请求地址上scroll=1m 表示此次查询的会话是一分钟,并且在这一分钟内不会查询到向ES中添加的新的数据。
GET /company-index/_search?scroll=1m
{
"query": {
"match_all": {}
},
"sort": [
{
"_doc": {
"order": "desc"
}
}
],
"size": 2
}
scroll每个批次查询的条数是: size * number_of_primary_shards
缺点: 数据并不是实时的。
nested数组查询
// 基本条件必须是nested类型
// 查询方式 从query下找到nested 内部再嵌套一个bool方法
// 类似于套娃
GET my-index-000001/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
}
}
Bucket聚合查询
// 普通的nested查询
GET /goods-info/_search
{
"size": 0,
"aggs": {
"per_count": {
"terms": {
"size":100,
"field": "brandId",
"min_doc_count":1
}
}
}
}
// 内部nested查询
GET /goods-info/_search
{
"size": 1,
"aggs": {
"personList": {
"nested": {
"path": "attrList"
},
"aggs": {
"aggsList": {
"terms": {
"field": "attrList.attrName",
"size": 10
}
}
}
}
}
}
金额区间查询
{
"query": {
"range": {
"reply": {
"gte": 245,
"lte": 250
}
}
}
}
gt:大于,gte:大于等于,lt:小于,lte:小于等于
日期区间查询
{
"query": {
"range": {
"postdate": {
"gte": "2016-09-01 00:00:00",
"lte": "2016-09-30 23:59:59",
"format": "yyyy-MM-dd HH:mm:ss"
}
}
}
}
查询非空字段
返回对应字段中至少有一个非空值的文档,也就是说,该字段有值
{
"query": {
"exists": {
"field": "user"
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kwUGDN98-1640421839328)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20211215234857174.png)]
查询多个id的值
GET /goods-info/_search
{
"query": {
"ids": {
"values": [1,2,3]
}
}
}
多个nested查询
{
"query": {
"bool": {
"must": [
{"nested": {
"path": "user",
"query": {
"term": {
"user.first": {
"value": "Li"
}
}
}
}},
{
"nested": {
"path": "user",
"query": {
"term": {
"user.last": {
"value": "Wang"
}
}
}
}
}
]
}
}
}