Elastic Search中DSL Query的常见语法
Query DSL是一种通过request body提交搜索参数的请求方式。就是将请求头参数(?xxx=xxx)转换为请求体参数。
语法格式:
GET [/index_name/type_name]/_search
{
"query_name" : {
"argument" : "value" [, ....]
},
"query_name" : {
"field_name" : {
"argument" : "value" [, ....]
}
}
}
4.1 测试数据
PUT /test_index
{
"mappings": {
"test_type" : {
"properties": {
"dept_name" : {
"type" : "keyword"
},
"emps.name" : {
"type" : "text",
"analyzer": "standard"
},
"emps.age" : {
"type": "long"
},
"num_of_emps" : {
"type": "long"
},
"tags" : {
"type" : "keyword"
}
}
}
}
}
PUT /test_index/test_type/1
{
"dept_name" : "Sales Department",
"emps" : [
{ "name" : "zhangsan", "age" : 20, "join_date" : "2018-07-10" },
{ "name" : "wangwu", "age" : 22, "join_date" : "2018-07-10" }
],
"num_of_emps" : 2,
"tags" : [ "Sales tag1", "Sales tag2", "Sales tag3" ]
}
PUT /test_index/test_type/2
{
"dept_name" : "Development Department",
"emps" : [
{ "name" : "Rod Johnson", "age" : 40, "join_date" : "2016-07-10" },
{ "name" : "James Gosling", "age" : 41, "join_date" : "2017-07-10" },
{ "name" : "Patrick Lencioni", "age" : 42, "join_date" : "2018-01-10" }
],
"num_of_emps" : 3,
"tags" : [ "Development tags1", "Development tags2", "Development tags3" ]
}
4.2 搜索案例
全查询
GET /test_index/test_type/_search
{
"query" : {
"match_all" : {}
}
}
单字段匹配
GET /test_index/test_type/_search
{
"query" : {
"match" : { "emps.name" : "zhangsan" }
}
}
组合条件:
用java来描述 : ( a > 3 && ( b < 10 || c == 6 ) )
bool - 用于组合多条件,相当于java中的布尔表达式。相当于最外层的括号,也就是完整的布尔表达式。
must - 必须符合要求, 相当于java中的逻辑运算符 ==或&&。在must范围内的条件都必须满足。
must_not - 必须不符合要求, 相当于java中的逻辑运算符 !
should - 有任意条件符合要求即可,相当于java中的逻辑运算符 ||,在should范围内的条件,只要有任意一个满足即可。
range - 数学比较条件。计算数学范围的。
常见的搜索方式在后续案例中演示。
GET /test_index/test_type/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"dept_name": "Sales Department"
}
}
],
"must_not": [
{
"range": {
"num_of_emps": {
"gt": 10
}
}
}
],
"should": [
{
"match": {
"emps.name": "wangwu"
}
},
{
"range": {
"emps.age": {
"lte": 10
}
}
}
]
}
}
}
4.2.1 match
根据某条件搜索document。match会根据field对应的analyzer对搜索条件做分词。并在倒排索引中搜索数据。
GET /_search
{
"query" : {
"match" : { "dept_name" : "Sales Department" }
}
}
4.2.2 multi match
使用搜索条件,在多个字段中进行全文检索,搜索document数据。也会将搜索条件使用字段的analyzer做分词。
GET /_search
{
"query" : {
"multi_match": {
"query": "rod",
"fields": ["dept_name", "emps.name"]
}
}
}
4.2.3 range
数学比较搜索
GET /_search
{
"query" : {
"range" : {
"emps.age" : {
"gt" : 21, "lte" : 45
}
}
}
}
在ES中range也可以实现日期的比较,如:查询40天以内入职的员工。其语法为:
GET /test_index/_search
{
"query": {
"range": {
"emps.join_date": {
"gte": "2018-08-10||-40d"
}
}
}
}
4.2.4 term
词组比较,词组搜索。
忽略搜索条件分词,使用搜索条件进行精确匹配。进行匹配搜索的字段mapping建议手工创建,且type值为keyword。ES在处理keyword类型的字符串时,不进行分词操作。term搜索可执行。ES中对数字,日期,boolean类型数据也不会做分词操作。
在ES5.x版本后,为text类型的field默认会创建一个子字段,子字段命名为field_name.keyword,这个字段是不做分词的,默认字段长度最大256个字符。
GET /_search
{
"query" : {
"term" : {
"dept_name" : "Sales Department"
}
}
}
4.2.5 terms
与term含义相同,就是可以比对多个搜索条件数据
GET /_search
{
"query" : {
"terms" : {
"tags" : [ "Sales tag1", "Development tags3" ]
}
}
}
4.2.6 复合搜索
在一个请求体中,有多个搜索条件,就是复合搜索。如:搜索数据,条件为部门名称是Sales Department,部门员工数量少于10人,部门员工入职时间晚于2017-01-01,部门员工中一定有人叫zhangsan。上述条件中,部门名称可选,部门员工数量必须满足要求,部门员工入职时间和人名有任意一个条件满足即可。
在执行复合条件搜索的时候,命令也是有内外顺序的。总体来说就是:"bool" : { "must" : { "action" : {} }, "should" : { "action" : {} }, "must_not" : { "action" : {} }, bool: {}}。 bool命令是可以嵌套的。而"action"代表的就是具体的比对方式,如:match,range等。
GET /test_index/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"num_of_emps": {
"lt": 10
}
}
}
],
"should": [
{
"match": {
"dept_name": "Sales Department"
}
},
{
"match": {
"emps.name": "zhangsan"
}
},
{
"range": {
"emps.join_date": {
"gte": "2017-01-01"
}
}
}
]
}
}
}
4.2.7 排序
在ES的搜索中,默认是使用相关度分数实现排序的。可以通过搜索语法实现定制化排序。
GET test_index/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"num_of_emps": {
"order": "asc"
}
},
{
"dept_name": {
"order": "desc"
}
}
],
"_source": ["dept_name", "num_of_emps"]
}
注意:在ES中,如果使用字符串类型的字段作为排序依据,可能会有问题,尤其是字段类型为text时,ES需要对字段数据做分词,建立倒排索引。如果使用text类型字段做排序,ES给出的排序结果未必友好,毕竟分词后,先使用哪一个单词做排序是不固定的。如:
PUT /test_sort/sort_type/1
{
"content" : "first content",
"order" : 1
}
PUT /test_sort/sort_type/2
{
"content" : "second content",
"order" : 2
}
GET /test_sort/sort_type/_search
{
"query" : {
"match" : {
"content" : "content"
}
},
"sort" : [
{
"content" : { "order" : "asc" }
}
]
}
此时需要对字段content进行特殊处理,处理如下:为字符串字段增加子字段sf(sort field),这个字段类型为keyword类型(不进行分词),排序时使用这个子字段content.sf作为排序字段即可。在ES5.x版本之后,ES默认为每一个text类型的字段建立一个子字段。子字段类型为keyword,可以实现排序机制。
DELETE /test_sort
PUT /test_sort
{
"mappings": {
"sort_type": {
"properties": {
"content" : {
"type": "text",
"analyzer": "standard",
"fields": {
"sf" : {
"type": "keyword"
}
}
},
"order" : {
"type": "long"
}
}
}
}
}
PUT /test_sort/sort_type/1
{
"content" : "first content",
"order" : 1
}
PUT /test_sort/sort_type/2
{
"content" : "second content",
"order" : 2
}
GET /test_sort/sort_type/_search
{
"query" : {
"match_all" : {}
},
"sort" : [
{
"content.sf" : { "order" : "desc" }
}
]
}
4.2.8 scroll搜索
如果需要一次性搜索出10万数据,那么执行效率一定不会很高,这个时候可以使用scroll滚动搜索的方式实现搜索。scroll滚动搜索类似分页,是在搜索的时候,先查询一部分,之后再查询下一部分,分批查询总体数据。可以实现一个高效的响应。
scroll搜索会在第一次搜索的时候保存一个快照,这个快照保存的时长由请求指定,后续的查询会依据这个快照执行再次查询。如果这个过程中,ES中的document发生了变化,是不会影响到原搜索结果的。
scroll搜索时,需要指定一个排序,可以使用_doc实现排序,这种排序性能更高一些。
scroll搜索的2次以后的请求,必须在指定的快照保存时长内发起,且每次请求都需要指定这个快照保存时长。
scroll搜索的返回结果一定会包含一个特殊的结果数据_scroll_id。这个数据就是scroll搜索的快照ID。scroll搜索的2次以后的请求,必须携带上这个ID,否则无法依据ES保存的快照执行后续的搜索。
测试:
GET /t_index/_search?scroll=1m
{
"query": {
"match_all": {}
},
"sort": [ "_doc" ],
"size" : 1
}
GET /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "根据具体返回结果替换"
}
scroll不是分页,不是用来替换分页搜索的技术。一般来说,分页是为用户提供数据的,scroll是为系统内部处理分批提供数据的。如:reindex 重建索引。
Elastic Search中DSL Query的常见语法的更多相关文章
- Elastic Search中filter的理解
在ES中,请求一旦发起,ES服务器是按照请求参数的顺序依次执行具体的搜索过滤逻辑的.如何定制请求体中的搜索过滤条件顺序,是一个经验活.类似query(指search中的query请求参数),也是搜索的 ...
- Elastic search中使用nested类型的内嵌对象
在大数据的应用环境中,往往使用反范式设计来提高读写性能. 假设我们有个类似简书的系统,系统里有文章,用户也可以对文章进行赞赏.在关系型数据库中,如果按照数据库范式设计,需要两张表:一张文章表和一张赞赏 ...
- Elastic Search中Document的CRUD操作
一. 新增Document在索引中增加文档.在index中增加document.ES有自动识别机制.如果增加的document对应的index不存在.自动创建,如果index存在,type不存在自动创 ...
- Elastic Search中Query String常见语法
1 搜索所有数据timeout参数:是超时时长定义.代表每个节点上的每个shard执行搜索时最多耗时多久.不会影响响应的正常返回.只会影响返回响应中的数据数量.如:索引a中,有10亿数据.存储在5个s ...
- Elastic Search中normalization和分词器
为key_words提供更加完整的倒排索引. 如:时态转化(like | liked),单复数转化(man | men),全写简写(china | cn),同义词(small | little)等. ...
- Elastic Search中mapping的问题
Mapping在ES中是非常重要的一个概念.决定了一个index中的field使用什么数据格式存储,使用什么分词器解析,是否有子字段,是否需要copy to其他字段等.Mapping决定了index中 ...
- elastic search文档详解
在elastic search中文档(document)类似于关系型数据库里的记录(record),类型(type)类似于表(table),索引(index)类似于库(database). 文档一定有 ...
- 超好用的Markdown编辑器Typora中的常见语法
目录 下载网址 安装 一.标题 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 二.语法环境 三.单选 四.字体 五.分割符 六.列表 七.图片引入 八.表格 九.超链接 下载网址 正版中 ...
- Elastic Search对Document的搜索
在ES中使用的重点.ES中存储的数据.核心就是为了提供全文搜索能力的.搜索功能非常重要.多练. 1 query string searchsearch的参数都是类似http请求头中的字符串参数提供搜索 ...
随机推荐
- codeforces#1196F. K-th Path(最短路,思维题)
题目链接: https://codeforces.com/contest/1196/problem/F 题意: 在无向图的所有最短路点对中,求出第$k$大 数据范围: $ 1 \leq k \leq ...
- 5.rabbitmq--通配符模式Topics
rabbitmq--通配符模式Topics topic模式也称为主题模式,其实他相对于routing模式最大的好处就是他多了一种匹配模式的路由,怎么理解匹配呢,其实就相当于我们之前正则的.*这种,不过 ...
- 【Redis 向Redis中批量导入mysql中的数据(亲自测试)】
转自:https://blog.csdn.net/kenianni/article/details/84910638 有改动,仅供个人学习 问题提出:缓存的冷启动问题 应用系统新版本上线,这时候 re ...
- python并发——进程间同步和通信
一.进程间同步 对于一些临界资源,不能使用并发无限消耗,就需要设置专门的临界标示,比如锁或者信号量等 from multiprocessing import Process, Lock import ...
- Mysql数据表字段扩充的小技巧
在开发中,往往需求变更比开发速度要快,就会存在一些问题,比如突然要增加一个字段,我们需要 alter table 表名 add [column] 字段名 数据类型 [列属性] [位置]; 然后修改实体 ...
- Final——Nishang
一.介绍 Nishang是基于PowerShell的渗透测试专用工具,它集成了框架.脚本和各种payload,被广泛应用于渗透测试的各个阶段. 二.使用 下载脚本工具:Nishang Nishang需 ...
- Linux之profile、bash_profile、bashrc文件
来自: profile.bash_profile.bashrc文件的作用与区别 1. profile 文件 1.1 profile 文件的作用 profile(/etc/profile),用于设置系统 ...
- kafka配置的问题排查
问题反馈: xx现场测试环境下,整个平台的数据,除了原始数据模块,其他模块正常运行.相同版本的包,在线上环境上原始数据的订阅是正常的,但是测试环境没有,查看所有相关的日志,均没有报异常,且日志中有正常 ...
- 前端知识点回顾——Javascript篇(一)
DOM特殊元素获取 document.documentElement //HTML标签 document.head //head标签 document.title //title标签 document ...
- 数据中心网络架构的问题与演进 — 云网融合与 SD-WAN
目录 文章目录 目录 前文列表 云网融合 云网融合的应用场景 SD-WAN SD-WAN 的应用场景 企业组网互联 SD-EN 数据中心互联 SD-DCI 云间互联 SD-CX 企业用户接入云 数据中 ...