官方文档:Query DSL
Query DSL:
Elasticsearch提供基于JSON的完整Query DSL
(域特定语言)来定义查询。可以将查询DSL看作查询的AST(抽象语法树),它由两类子句组成:
- 叶查询子句:叶查询子句在特定字段中查找特定值,如
match
,term
或range
查询。这些查询可以自己使用。 复合查询子句:复合查询子句包装其他叶或复合查询,并用于以逻辑方式组合多个查询(如
bool
或dis_max
查询),或更改它们的行为(如constant_score
查询)。
导入测试数据:
curl -H "Content-Type: application/json" -XPOST '192.168.20.60:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json"
数据样例:
# curl -XGET '192.168.20.60:9200/bank/account/1?pretty'
{
"_index" : "bank",
"_type" : "account",
"_id" : "1",
"_version" : 1,
"found" : true,
"_source" : {
"account_number" : 1,
"balance" : 39225,
"firstname" : "Amber",
"lastname" : "Duke",
"age" : 32,
"gender" : "M",
"address" : "880 Holmes Lane",
"employer" : "Pyrami",
"email" : "amberduke@pyrami.com",
"city" : "Brogan",
"state" : "IL"
}
}
简单查询:
- 指定index名以及type名的搜索
GET /bank/account/_search?q=* #*表示所有文档
GET /bank/account/_search?q=gender:M
- 指定index名没有type名的搜索
GET /bank/_search?q=gender:M
- 既不指定index也不指定type的集群内搜索
GET /_search?q=gender:M
等价于:
GET /bank/account/_search
{
"query": {
"match": {
"gender": "M"
}
}
}
查询结果说明:
took #Elasticsearch花费了几毫秒的时间来执行搜索,单位毫秒
timed_out #搜索是否超时
_shards #搜索了多少碎片,以及搜索碎片成功/失败的次数
hits #搜索结果
hits.total #符合我们搜索条件的文档总数
hits.hits #实际的搜索结果数组(默认为前10个文档)
hits._score和max_score #现在忽略这些字段
控制查询返回的数量 from
和size
:
相当于mysql里的limit,from:从哪个结果开始返回;size:定义返回最大结果数(默认十个)
GET /bank/account/_search
{
"version": "true", #返回版本号
"query": {
"match": {
"gender": "M"
}
},
"from": 10,
"size": 2,
"_source": ["age","gender"]
}
Source Filtering
:过滤返回结果中_source
中的字段,主要有如下几种方式:
1.url参数
GET /myindex/_search?_source=username
2.不返回_source
GET /myindex/_search
{
"_source": false
}
3.返回部分字段
GET /myindex/_search
{
"_source": ["age","gender"]
}
GET my_index/_search
{
"_source": {
"include": "*i*",
"exclude": "birth"
}
}
Count API
:获取符合条件的文档数,endpoint为_count
GET /myindex/_count
{
"query": {
"match": {
"FIELD": "TEXT"
}
}
}
全文查询:
全文查询 | 解释说明 |
---|---|
match | 执行全文查询的标准查询,包括模糊匹配和短语或近似查询 |
match_phrase | 与match查询类似,但用于匹配精确短语或单词近似匹配 |
match_phrase_prefix | 与match_phrase查询类似,但对最后一个单词进行通配符搜索 |
multi_match | match查询的多字段版本 |
common_terms | 一个更专门的查询,让更多的偏好非常用的单词 |
query_string | 支持紧凑的Lucene 查询字符串语法,允许您在单个查询字符串中指定AND |
simple_query_string | query_string适合直接向用户公开 的语法更简单,更健壮的版本 |
Match Query
:match查询接受文本/数字/日期,分析它们并构建查询
匹配地址中包含“mill”或“lane”的所有帐户:
GET /_search
{
"query":{
"match":{
"address": "mill lane"
"operator" : "or"
}
}
}
请注意,address是一个字段的名称,您可以替换任何字段的名称。match查询是类型的boolean。这意味着分析提供的文本,分析过程从提供的文本构建布尔查询。operator
标志可以设置为or或and 控制布尔子句(默认为or)。
通过
operator
参数可以控制单词间的匹配关系,可选项为or和and(默认为or)
通过minimum_should_match
参数可以控制需要匹配的单词数
Match Phrase Query
:
匹配短语“mill lane”
GET /_search
{
"query": {
"match_phrase" : {
"address": "mill lane"
}
}
}
Multi Match Query
:match查询的多字段版本
GET /_search
{
"query":{
"multi_match":{
"query": "46061700731",
"fields": ["event","imei"]
}
}
}
query:查询的字符串
fields:要查询的字段,字段可以用通配符指定:如”*_name”表示查询字段first_name和last_name。
^:表示提升单个字段,”fields” : [ “subject^3”, “message” ]表示subject字段的重要性是message的三倍
术语级别查询:
尽管全文查询将在执行之前分析查询字符串,但术语级别查询会根据存储在倒排索引中的确切术语进行操作,并且会在仅对keyword
具有normalizer
属性的字段执行之前对术语进行规范化。
这些查询通常用于结构化数据,如数字,日期和枚举,而不是全文字段。或者,它们允许您创建低级查询,并在分析过程之前进行。
术语级别查询 | 解释说明 |
---|---|
term | 查找某字段里面有某个关键词的文档 |
terms | 查找包含指定字段中指定的任何确切术语的文档 |
terms_set | 查找与一个或多个指定条款匹配的文档。必须匹配的术语数量取决于指定的最小值应匹配字段或脚本 |
range | 查找指定字段包含指定范围内的值(日期,数字或字符串)的文档 |
exists | 查找指定字段包含任何非空值的文档 |
prefix | 查找指定字段中包含以指定的确切前缀开头的术语的文档 |
wildcard | 查找指定字段包含与指定模式匹配的术语的文档,其中模式支持单字符通配符(?)和多字符通配符(*) |
regexp | 查找指定字段中包含与指定正则表达式匹配的字词的文档 |
fuzzy | 查找指定字段中包含与指定字词模糊相似的字词的文档。测量模糊度的 Levenshtein编辑距离 为1或2 |
type | 查找指定类型的文档 |
ids | 查找具有指定类型和ID的文档 |
match
和term
的区别是,match查询的时候,elasticsearch会根据你给定的字段提供合适的分析器,而term查询不会有分析器分析的过程。
term
查询
GET /bank/account/_search
{
"query":{
"term": {
"address": "mill"
}
}
}
terms
查询
GET /bank/account/_search
{
"query": {
"terms": {
"address": ["mill","lane"]
}
}
}
sort
排序 desc:降序; asc:升序
GET /bank/account/_search
{
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
prefix
:前缀匹配查询
搜索firstname以r开头的文档:
GET /bank/account/_search
{
"query": {
"prefix": {
"firstname": {
"value": "r"
}
}
}
}
range
控制范围
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
gte #大于或等于
gt #大于
lte #小于或等于
lt #小于
boost #设置查询的权值,默认为1.0
GET /bank/account/_search
{
"query": {
"range": {
"age": {
"gt": 10,
"lt": 30
}
}
}
}
range
针对日期做查询:
GET /myindex/_search
{
"query": {
"range": {
"birth": {
"gte": "1990-01-01"
}
}
}
}
GET /myindex/_search
{
"query": {
"range": {
"birth": {
"gte": "now-20y"
}
}
}
}
now
:基准日期,也可以是具体日期,比如2018-01-01,使用具体日期的时候要使用||做隔离
-20y
:计算公式,主要有3种:+1h,-1d,/d
(将时间舍入到天)
wildcard
(影响性能):允许使用通配符和?来进行查询; :一个多个字符; ?:仅代表一个字符
GET /bank/account/_search
{
"query": {
"wildcard": {
"firstname": {
"value": "r*f"
}
}
}
}
复合查询:
复合查询 | 解释说明 |
---|---|
constant_score | 包含另一个查询的查询,但在过滤器上下文中执行该查询。所有匹配的文件都被赋予相同的“常量” _score |
bool | 用于组合多个叶或化合物查询子句,作为默认查询 must,should,must_not,或filter条款。在must和should 条款有他们的分数相结合-更匹配的条款,更好的-而must_not和filter条款在过滤器上下文中执行 |
dis_max | 一个接受多个查询的查询,并返回与任何查询子句匹配的任何文档。虽然bool查询结合了所有匹配查询的分数,但dis_max查询使用单个最佳匹配查询子句的分数 |
function_score | 使用函数修改主查询返回的分数,以考虑流行度,新近度,距离或使用脚本实现的自定义算法等因素 |
boosting | 返回与positive查询匹配的文档,但会降低也与negative查询匹配的文档的得分 |
1.Constant Score Quer
该查询将其内部的插叙结果文档得分都设定为1或者boost
的值,多用于结合bool查询实现自定义得分
GET /myindex/_search
{
"query": {
"constant_score": {
"filter": {
"match":{
"username":"alfred"
}
}
}
}
}
2.Bool Query
布尔查询由一个或多个布尔子句组成,主要包含如下4个:
must: #条件必须满足,相当于and,对于一个文档,所有的查询都必须为真,这个文档才能够匹配成功
should: #相当于or,对于一个文档,查询列表中,只要有一个查询匹配,那么这个文档就被看成是匹配的
must_not: #相当于not,对于一个文档,查询列表中的的所有查询都必须都不为真,这个文档才被认为是匹配的
filter: #只过滤符合条件的文档,不计算相关性得分
filter:
es针对filter会有智能缓存,因此其执行效率很高,做简单匹配查询且不考虑算分时,推荐使用filter代替query
should:
使用分两种情况:
- bool查询中包含should,不包含must查询(文档必须满足至少一个条件,
minimum_should_match
可以控制满足条件的个数或百分比) - bool查询中同时包含should和must查询(文档不必满足should中的条件,但是如果满足条件,会增加相关性得分)
# select account from bank where age=28
GET /bank/account/_search
{
"query": {
"bool": {
"filter": {
"term": {
"age": "28"
}
}
}
}
}
匹配年龄不是36,并且账户在20000到30000之间的女性:
GET /bank/account/_search
{
"query": {
"bool": {
"must":{
"match": {"gender":"M"}
},
"must_not": [
{
"match": {"age":36}
}
],
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}
匹配年龄是36,并且账户在20000到30000之间的女性:
GET /bank/account/_search
{
"query": {
"bool": {
"must":[
{"match": {"gender":"M"}},
{"match": {"age":36}}
],
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}