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). 文档一定有 ...
-
Elastic Search对Document的搜索
在ES中使用的重点.ES中存储的数据.核心就是为了提供全文搜索能力的.搜索功能非常重要.多练. 1 query string searchsearch的参数都是类似http请求头中的字符串参数提供搜索 ...
-
elastic search book [ ElasticSearch book es book]
谁在使用ELK *, github都使用 ELK (ElasticSearch es book) ElasticSearch入门 Elasticsearch入门,这一篇就够了==>http ...
随机推荐
-
EA使用
类逻辑图 关系1:泛化(继承),Driver和Northeastermer继承了Person类 关系2:实现,Northeastermer实现了LivingLeiFeng类 关系3: 关联,两个对象 ...
-
ionic 嵌套view 的方法
我一直想在一个页面的同一个 DIV 里面嵌入一个不同的 HTML文件 ....但是总是没有达到我要的效果.....才发现原来我没有加一个 name 我用angular-ui 插件 里面的样式 总是 ...
-
IPSec协议
IPSec协议:IPsec将IP数据包的内容先加密再传输,即便中途被截获,由于缺乏解密数据包所必要的密钥,攻击者也无法获取里面的内容. 传输模式和隧道模式:IPsec对数据进行加密的方式有两种:传输模 ...
-
vim配置文件(本人喜欢的风格)
在/etc/vimrc这个文件 if v:lang =~ "utf8$" || v:lang =~ "UTF-8$" set fileencodings=utf ...
-
Python播放、关闭音乐代码
1.安装pygame:win + r :打开控制台输入:pip install pygame 2.#导入 import time import pygame 3.设置音乐绝对路径 #音乐路径 file ...
-
深入理解JVM(二)Java内存区域
2.1 C.C++内存管理是由开发人员管理,而Java则交给了JVM进行自动管理 2.2 JVM运行时数据区:方法区.堆(运行时线程共享),虚拟机栈.本地方法栈.程序计数器(运行时线程隔离,私有) 1 ...
-
C++ 保留有效小数 保留有效数字
1.需要头文件 #include <iomanip> 2. 要保留两位有效小数 cout<<setiosflags(ios::fixed)<<setprecisio ...
-
golang 内存占用测量
web服务中加入如下 import ( "runtime" "time" "fmt" ) go func() { for { var m r ...
-
MSSQL数据表生成模型
MSSQL数据表生成模型 http://pan.baidu.com/s/1mhBAapy
-
vc中nmake.exe cl.exe 的使用
首先简单介绍一下程序是如何编译链接的.程序写好之后,我们进行编译和链接来产生可执行程序.这时候,编译器为了完成编译和链接,需要知道很多信 息.比如要编译的文件是哪一个,使用哪些编译选项进行编译,编译好 ...