Elasticsearch高级查询Query DSL
Elasticsearch高级查询Query DSL
一、高级查询Query DSL简介
1、Query DSL(简介
Elasticsearch中提供了一种强大的检索数据方式,这种检索方式称之为Query DSL(Domain Specified Language) 。
Query DSL是利用 Rest API传递 JSON格式的请求体(RequestBody)数据与 ES进行交互,这种方式的丰富查询语法让 ES检索变得更强大,更简洁。
基本语法:
GET /es_db/_doc/_search {json请求体数据}
#可以简化为下面写法
GET /es_db/_search {json请求体数据}
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl.html
2、测试数据
示例数据:
#创建索引,并指定ik分词器
PUT /db_idx4
{
"settings":{
"index":{
"analysis.analyzer.default.type":"ik_max_word"
}
}
}
# 批量创建文档
POST _bulk
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":1}}
{"id":1,"name":"赵子龙","sex":1,"age":18, "address":"三国演义常山赵子龙", "desc":"刘备大将之一"}
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":2}}
{"id":2,"name":"赵云","sex":1,"age":19, "address":"王者打野刺客赵云", "desc":"王者刺客"}
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":3}}
{"id":3,"name":"关云长","sex":1,"age":23, "address":"三国演义关云长", "desc":"桃园结义刘备二弟"}
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":4}}
{"id":4,"name":"关羽","sex":1,"age":23, "address":"王者边路", "desc":"可辅可边"}
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":5}}
{"id":5,"name":"张益德","sex":1,"age":22, "address":"三国演义张益德", "desc":"桃园结义刘备三弟"}
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":6}}
{"id":6,"name":"张飞","sex":1,"age":22, "address":"王者辅助", "desc":"王者辅助"}
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":7}}
{"id":7,"name":"张玄德","sex":1,"age":25, "address":"三国演义张玄德", "desc":"桃园结义刘皇叔"}
{"index":{"_index":"db_idx4", "_type":"_doc", "_id":8}}
{"id":8,"name":"小乔","sex":0,"age":18, "address":"三国演义小乔", "desc":"周瑜之妻"}
二、查询操作
1、查询所有match_all
使用 match_all,默认只会返回 10条数据。
原因:_search查询默认采用的是分页查询,每页记录数 size的默认值为 10。如果想显示更多数据,指定 size 。
#使用 match_all,默认只会返回 10条数据。
GET /db_idx4/_search
#等同于
GET /db_idx4/_search
{
"query":{
"match_all":{
}
}
}
1.1 指定条数size
size 关键字:指定查询结果中返回指定条数。 默认返回值10条。
# 指定 size
GET /db_idx4/_search
{
"query":{
"match_all":{
}
},
"from":1,
"size":3
}
1.2 分页查询form
from 关键字:用来指定起始返回位置,和size关键字连用可实现分页效果
GET /db_idx4/_search
{
"query":{
"match_all":{
}
},
"from":2,
"size":200
}
如果 size = 30000,,就会出现异常。
- 查询结果的窗口太大,from + size的结果必须小于或等于10000。
- 查询结果的窗口的限制可以通过参数 index.max_result_window进行设置。
- 也可以采用 scroll api更高效的请求大量数据集。
#修改现有某个的索引
PUT /db_idx4/_settings
{
"index.max_result_window":"20000"
}
2、深分页查询Scroll
改动 index.max_result_window参数值的大小,只能解决一时的问题,当索引的数据量持续增长时,在查询全量数据时还是会出现问题。而且会增加 ES服务器内存大结果集消耗完的风险。
最佳实践还是根据异常提示中的采用 scroll api更高效的请求大量数据集。
GET /db_idx4/_search?scroll=1m
{
"query":{
"match_all":{
}
},
"size":2
}
查询结果: 除了返回前2条记录,还返回了一个游标ID值_scroll_id
。
2.1 采用游标id查询:
# scroll_id 的值就是上一个请求中返回的 _scroll_id 的值
GET /_search/scroll
{
"scroll":"1m",
"scroll_id":"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFmNpTWtscHBSUnVxYmM0ZEtrc1hGMGcAAAAAAAA1ABZlYko0RmdtUlNUT0ItcUo2TDNMbjdn"
}
多次根据 scroll_id游标查询,直到没有数据返回则结束查询。采用游标查询索引全量数据, 更安全高效,限制了单次对内存的消耗。
3、指定字段排序sort
注意:会让得分失效。
GET /db_idx4/_search
{
"query":{
"match_all":{
}
},
"sort":[
{
"age":"desc"
}
]
}
4、_source返回指定字段
_source 关键字:是一个数组,在数组中用来指定展示那些字段。
GET /db_idx4/_search
{
"query": {
"match_all": {}
},
"_source": ["name","address"]
}
5、match 查找
match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找
。
match支持下面几个参数:
- query:指定匹配的值
- operator:匹配条件类型
- and:条件分词后都要匹配
- or:条件分词后有一个匹配即可(默认)
- minmum_should_match :最低匹配度,即条件在倒排索引中最低的匹配度
#模糊匹配 match 分词后or的效果
GET /db_idx4/_search
{
"query": {
"match": {
"address": "王者打野"
}
}
}
#分词后 and的效果
GET /db_idx4/_search
{
"query": {
"match": {
"address": {
"query": "王者打野",
"operator": "and"
}
}
}
}
当 operator参数设置为 or时,minnum_should_match参数用来控制匹配的分词的最少数量。
#最少匹配打野,刺客两个词
GET /db_idx4/_search
{
"query": {
"match": {
"address": {
"query": "刺客打野",
"operator": "or",
"minimum_should_match": 2
}
}
}
}
6、多字段查询multi_match
multi_match 关键字:可以根据字段类型,决定是否使用分词查询,得分最高的在前面。
GET /db_idx4/_search
{
"query":{
"multi_match": {
"query": "王者打野",
"fields": ["address", "desc"]
}
}
}
注意:
字段类型分词,将查询条件分词之后进行查询,如果该字段不分词就会将查询条件作为整体进行查询。
7、query_string 查询
允许我们在单个查询字符串中指定 AND | OR | NOT条件,同时也和 multi_match query 一样,支持多字段搜索。和match类似,但是 match需要指定字段名,query_string是在所有字段中搜索,范围更广泛。
注意:
查询字段分词就将查询条件分词查询,查询字段不分词将查询条件不分词查询。
#未指定字段查询
GET /db_idx4/_search
{
"query":{
"query_string": {
"query": "赵云 OR 赵子龙"
}
}
}
#指定单个字段查询
GET /db_idx4/_search
{
"query":{
"query_string": {
"default_field": "address",
"query": "赵云 OR 赵子龙"
}
}
}
#指定多个字段查询
GET /db_idx4/_search
{
"query":{
"query_string": {
"fields": ["address","name"],
"query": "赵云 OR 赵子龙 OR 张飞"
}
}
}
8、simple_query_string 查询语法
类似Query String,但是会忽略错误的语法,同时只支持部分查询语法,不支持AND OR NOT,会当作字符串处理。
支持部分逻辑:
- “+” 替代AND
- “|” 替代OR
- “-” 替代NOT
#simple_query_string 默认的operator是OR
GET /db_idx4/_search
{
"query":{
"simple_query_string": {
"query": "王者打野",
"fields": ["address","desc"],
"default_operator": "OR"
}
}
}
GET /db_idx4/_search
{
"query":{
"simple_query_string": {
"query": "王者+打野",
"fields": ["address","desc"]
}
}
}
9、关键词查询Term
Term用来使用关键词查询(精确匹配),还可以用来查询没有被进行分词的数据类型。
- term是表达语意的最小单位,搜索和利用统计语言模型进行自然语言处理都需要处理Term。
- match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找,而 term会直接对关键词进行查找。
一般模糊查找的时候,多用 match,而精确查找时可以使用 term。
在 ES中默认使用分词器为标准分词器(Standard Analyzer)标准分词器对于英文单词分词,对于中文单字分词。
在 ES的 Mapping Type 中 keyword,date,integer,long,double,boolean or ip 这些类型不分词,只有 text类型分词。
GET /db_idx4/_search
{
"query": {
"term": {
"address.keyword": "三国演义小乔"
}
}
}
可以通过 Constant Score 将查询转换成一个 Filtering,避免算分,并利用缓存,提高性能。
GET /db_idx4/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"address.keyword": "三国演义小乔"
}
}
}
}
}
对bool,日期,数字,结构化的文本可以利用 term做精确匹配。
GET /db_idx4/_search
{
"query": {
"term": {
"age": {
"value": 18
}
}
}
}
10、范围查询range
range:范围关键字:
- gte 大于等于
- lte 小于等于
- gt 大于
- lt 小于
- now 当前时间
POST /db_idx4/_search
{
"query": {
"range": {
"age": {
"gte": 18,
"lte": 20
}
}
}
}
11、日期range
DELETE /product
POST /product/_bulk
{"index":{"_id":1}}
{"price":100,"date":"2022‐01‐01","productId":"XHDK‐1293"}
{"index":{"_id":2}}
{"price":200,"date":"2022‐02‐01","productId":"KDKE‐5421"}
GET /product/_mapping
GET /product/_search
{
"query": {
"range": {
"date": {
"lte": "now‐2y"
}
}
}
}
12、多id查询ids
ids 关键字 :值为数组类型,用来根据一组id获取多个对应的文档。
GET /db_idx4/_search
{
"query": {
"ids": {
"values": [
1,
2
]
}
}
}
13、高亮highlight
highlight 关键字:可以让符合条件的文档中的关键词高亮。
highlight相关属性:
- pre_tags 前缀标签
- post_tags 后缀标签
- tags_schema 设置为 styled可以使用内置高亮样式
- require_field_match 多字段高亮需要设置为false
GET /db_idx4/_search
{
"query": {
"term": {
"address": {
"value": "王者"
}
}
},
"highlight": {
"fields": {
"*": {}
}
}
}
13.1 自定义高亮html标签
可以在highlight中使用 pre_tags和 post_tags。
GET /db_idx4/_search
{
"query": {
"term": {
"address": {
"value": "王者"
}
}
},
"highlight": {
"post_tags": [
"</span>"
],
"pre_tags": [
"<span style='color:red'>"
],
"fields": {
"*": {}
}
}
}
13.2 多字段高亮
GET /db_idx4/_search
{
"query": {
"term": {
"address": {
"value": "王者"
}
}
},
"highlight": {
"pre_tags": [
"<font color='red'>"
],
"post_tags": [
"<font/>"
],
"require_field_match": "false",
"fields": {
"address": {},
"desc": {}
}
}
}
更多使用可查看官方文档。
– 求知若饥,虚心若愚。
更多推荐
所有评论(0)