es提供Search API使我们能够对es中存储的数据进行查询分析,endpoint为_search,有以下查询形式:

  • GET /_search
  • GET /my_index/_search
  • GET /my_index1,my_index2/_search
  • GET /my_*/_search

通过url query参数来实现查询,常用参数如下:

q 指定查询的语句,默认语法 Query String Syntax

df q中不指定字段时默认查询的字段,如果不指定,es会查询所有字段

sort 排序,asc升序 desc降序

timeout 指定超时时间,默认不超时

from,size 用于分页

范查询

在所有字段中匹配 alfred 的值,返回相关匹配的文档

# 开启profile参数可以对查询效率优化
GET test_search/_search?q=alfred
{
"profile": true
}

指定字段查询

查找username含有alfred的文档

GET test_search/_search?q=username:alfred
{
"profile": true
}

查找username含有alfred或 所有字段中匹配way的文档

# alfred和way之间的空格会被当做“或” 即查找username:alfred 或者 查找所有含有way的文档,way查询会被当成范查询,在所有字段中查找
GET test_search/_search?q=username:alfred way
{
"profile": true
}

查找username含有alfred way的文档

GET test_search/_search?q=username:"alfred way"
{
"profile": true
}

查找username含有alfred或者username含有way的文档

GET test_search/_search?q=username:(alfred way)
{
"profile": true
}

布尔操作符

  • AND(&&)、OR(||)、NOT(!)
  • +-分别对应must和must not

+在url中会被解析成空格,要使用%2B代替

查找username含有alfred 且 所有字段中匹配way的文档

# alfred只会在username中查找,way的查询会使用范查询
GET test_search/_search?q=username:alfred AND way
{
"profile": true
}

查找username含有alfred且username含有way的文档

GET test_search/_search?q=username:(alfred AND way)
{
"profile": true
}

查找username含有alfred且username不含有way的文档

GET test_search/_search?q=username:(alfred NOT way)
{
"profile": true
}

查找username含有alfred且username含有way的文档

GET test_search/_search?q=username:(alfred %2Bway)
{
"profile": true
}

范围查询

支持数字和日期

(1)区间写法

  • age:[1 TO 10] 意为 1<=age<=10
  • age:[1 TO 10} 意为 1<=age<10
  • age:[1 TO ] 意为 age>=1
  • age:[* TO 10] 意为 age<=10

(2)算数符号写法

  • age:>=1
  • age:(>=1 && <=10) 或者 age:(+>1 +<10)

查找username含有alfred或者age大于20的文档

GET test_search/_search?q=username:alfred age:>20
{
"profile": true
}

查找birth在1980到1990之间的文档

GET test_search/_search?q=birth:(>1980 AND <1990)
{
"profile": true
}

通配符查询

通配符匹配执行效率低,且占用较多内存,不建议使用

如无特殊需求,不要将 ?/* 放在最前面

?代表1个字符, *代表0或多个字符

  • name:t?m
  • name:torn*
  • name:t*m

查找username含有alf开头的所有文档

GET test_search/_search?q=username:alf*
{
"profile": true
}

正则表达式

与通配符类似,正则表达式也比较持内存

模糊匹配

  • name:roam~1
  • 匹配与roam差一个词,比如 foam roams等
GET test_search/_search?q=username:alfed~1
{
"profile": true
}

近似度查询

  • “fox quick”~5
  • 以term为单位进行差异比较,比如”quick fox” “quick brown fox” 都会被匹配,允许有5个单位的差异
GET test_search/_search?q=username:"alfred"~1
{
"profile": true
}

Query DSL

基于JSON定义的查询语言,主要分为字段类查询和复合查询

字段类查询

主要分为以下2类

(1)全文匹配

针对text类型的字段进行全文检索,会对查询语句先进行分词处理,如match、match_path、等query类型

(2)单词匹配

不会对查询语句做分词处理,会直接匹配字段的倒排索引,如term、terms、range等query类型

match

查找username含有alfred或者username含有way的文档

# 会将 alfred way 先进行分词
GET test_search/_search
{
"query": {
"match": {
"username": "alfred way"
}
}
}

查找username含有alfred且username含有way的文档

# 提供 operator 参数控制查询语法且或关系,operator默认为or
GET test_search/_search
{
"query": {
"match": {
"username": {
"query": "alfred way",
"operator": "and"
}
}
}
}

查找 username含有alfred、username含有way、username含有room 至少满足2个条件的文档

# username中含有alfred、way、room三个单词,只要满足含有其他任意2个,就匹配
GET test_search/_search
{
"query": {
"match": {
"username": {
"query": "alfred way room",
"minimum_should_match": "2"
}
}
}
}

match_phrase

以字段作检索,词语查询,顺序检索

GET test_search/_search
{
"query": {
"match_phrase": {
"username": "alfred way"
}
}
}
# 使用slop参数可以控制查询词语的差异,这里就是最多允许有一个单词的差异
GET test_search/_search
{
"query": {
"match_phrase": {
"username": {
"query": "alfred way",
"slop": "1"
}
}
}
}

query_string

完全类似于上面url方式的查询

GET test_search/_search
{
"query": {
"query_string": {
"default_field": "username",
"query": "alfred AND way"
}
}
}
GET test_search/_search
{
"query": {
"query_string": {
"fields": [
"username",
"job"
]
"query": "alfred OR (way AND room)"
}
}
}

simple_query_string

类似query_string,但是会忽略错误的查询语法,并且仅支持部分查询语法

不能使用AND、OR、NOT等关键词

  • +代指AND
  • |代指OR
  • -代指NOT
GET test_search/_search
{
"query": {
"query_string": {
"fields": [
"username"
]
"query": "alfred | way"
}
}
}

term

将查询语句作为整个单词进行查询,即不对查询的语句进行分词

查询username含有alfred的文档

GET test_search/_search
{
"query": {
"term": {
"username": "alfred"
}
}
}

查询username含有alfred way的文档

# alfred way会被作为一整块在倒排索引中查找
GET test_search/_search
{
"query": {
"term": {
"username": "alfred way"
}
}
}

terms

查询某个字段里含有多个关键词的文档

GET test_search/_search
{
"query": {
"terms": {
"username": [
"alfred",
"way"
]
}
}
}

range

范围查询主要针对数值和日期类型

查询age大于等于10,小于等于20的文档

GET test_search/_search
{
"query": {
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
}

查询birth大于等于1990-01-01的文档

GET test_search/_search
{
"query": {
"range": {
"birth": {
"gte": "1990-01-01"
}
}
}
}

查询 birth大于等于当前时间-30年的文档

GET test_search/_search
{
"query": {
"range": {
"birth": {
"gte": "now-30y"
}
}
}
}

复合查询

指包含字段类查询或复合查询类型,主要包含:

  • constant_soure query
  • bool query
  • dis_max query
  • function_score query
  • boosting query

bool query

它由一个或多个子句组成,每个子句都有特定的类型:

must:返回的文档必须满足must子句的条件,并且计算相关性得分

filter:返回的文档必须满足filter子句条件,但是不计算相关性得分

must_not:返回的文档必须不满足must_not条件

should:如果查询中指包含should(不包含must),文档至少满足一个条件(但是可以通过minimum_should_match控制满足条件的个数或者百分比);如果同时存在should和must,文档不必满足should条件,如果满足should条件,可以增加相关性得分

Count API

获取符合条件的文档数,endpoint为_count

GET test_search/_count
{
"query": {
"range": {
"birth": {
"gte": "now-30y"
}
}
}
}

Source Filtering

过滤返回结果中_source中的字段,主要有以下几种方式:

(1)url参数

GET test_search/_search?_source=username

(2)不返回_source

GET test_search/_search
{
"_source": false
}

(3)返回部分字段

GET test_search/_search
{
"_source": ["username","age"]
}
GET test_search/_search
{
"_source": {
"includes": "*i*",
"excludes": "birth"
}
}