Elasticsearch查询API使用

Elasticsearch查询API简介

查询API

在Elasticsearch支持以如下几种Restful API对存储的文档进行查询:


#不指定index的查询
GET /_search
POST /_search

#指定index的查询,其中<index>可以是特定的index名称,也可以是一组以逗号隔开的index列表,或者是符合*通配符的一系列索引index
GET /<index>/_search
POST /<index>/_search

#指定index和type的查询,其中<type>可以是特定的type名称,也可以是一组以逗号隔开的type列表,或者是符合*通配符的一系列type
GET /<index>/<type>/_search
POST /<index>/<type>/_search

查询条件

在使用查询API的时候,根据查询条件传递方式的不同有如下两种查询方式:

查询字符串

查询字符串(也称为简单查询或者轻量查询)是像传递URL参数一样去传递查询语句,被称为简单搜索或查询字符串(query string)搜索,例如:

GET /twitter/_search?q=user:kimchy

结构化查询

结构化查询也被称为DSL查询(Query DSL),DSL是Elasticsearch提供的一种丰富且灵活的查询语言,该语言以json请求体的形式出现,通过restful请求与Elasticsearch进行交互,例如:

GET /twitter/_search
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

查询返回结果

Elasticsearch查询的返回结果有统一的结构,以下返回结果每一个部分的简要说明:

{
    "took": 1,  //耗时,毫秒
    "timed_out": false,  //是否超时
    "_shards":{  //查询了多少个分片
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
    },
    "hits":{
        "total" : 1,  //总命中数
        "max_score": 1.3862944,  //最高得分
        "hits" : [  //命中的文档列表
            {
                "_index" : "twitter",  //index名称
                "_type" : "_doc",  //type名称
                "_id" : "0",  //文档ID
                "_score": 1.3862944,  //相关性得分
                "_source" : { //原始的文档数据
                    "user" : "kimchy",
                    "message": "trying out Elasticsearch",
                    "date" : "2009-11-15T14:12:12",
                    "likes" : 0
                }
            }
        ]
    }
}

查询结果分页

类似SQL可以使用LIMIT关键字可以对查询结果进行分类类似Elasticsearch使用fromsize参数进行分页。

  • size——显示应该返回的结果数量,默认是10
  • from——显示应该跳过的初始结果数量,默认是0

搜索请求耗用的堆内存和时间与 from + size 大小成正比。分页越深耗用越大,为了不因分页导致OOM或严重影响性能,ES中规定from + size不能大于索引setting参数index.max_result_window的值,默认值为10000。

search_after用于在指定文档后面取文档,可用于深度分页,即在获取下一页的时候需要传入上次获取的最后一个文档。

注意:使用search_after,要求查询必须指定排序,并且这个排序组合值在每个文档唯一(最好排序中包含_id字段,这样可以保证唯一)。

search_after的值用的就是这个排序值。用search_after时 from 只能为0、-1。

查询结果排序

在Elasticsearch中, 相关性得分由一个浮点数进行表示,并在搜索结果中通过_score参数返回, 默认的返回结果排序是安卓_score降序排列。

如果需要指定特定的排序可以通过参数sort来指定,与SQL类似,asc表示升序排列,desc表示降序排列

查询字符串参数

使用查询字符串进行查询的方式中,常用的查询参数如下:

配置项 描述
q 此参数用于指定查询字符串。
lenient 基于格式的错误可以通过将此参数设置为true来忽略,默认情况下为false。
fields 此参数用于在响应中选择文档返回字段,默认情况下返回全部字段。
sort 可以通过使用这个参数获得排序结果,这个参数的可能值是fieldName,fieldName:asc和fieldname:desc
timeout 使用此参数限定搜索时间,响应只包含指定时间内的匹配。默认情况下,无超时。
terminate_after 可以将响应限制为每个分片的指定数量的文档,当到达这个数量以后,查询将提前终止。 默认情况下不设置terminate_after。
frpm 从命中的索引开始返回,默认值为0。
size 它表示要返回的命中数,默认值为10。

查询表达式

查询表达式(Query DSL)是一种非常灵活又富有表现力的查询语言。 Elasticsearch使用它可以以简单的JSON接口来展现Lucene功能的绝大部分。

要使用这种查询表达式,只需将查询语句传递给query参数。

查询语句(Query clauses)就像一些简单的组合块,这些组合块可以彼此之间合并组成更复杂的查询,这些语句可以是如下形式:

  • 叶子语句——就像match语句,被用于将查询字符串和一个字段(或者多个字段)对比。
  • 复合语句——主要用于合并其它查询语句。 比如,一个bool语句 允许在你需要的时候组合其它语句,无论是must匹配、must_not匹配还是should匹配,同时它可以包含filters。

一条复合语句可以合并任何其它查询语句,包括复合语句,这就意味着,复合语句之间可以互相嵌套,可以表达非常复杂的逻辑。

如上所述Elasticsearch的查询语句可以通过组合进行搭配,但是进行搭配的组合套件只能是过滤查询或者评分查询。如果使用了filter关键字就是过滤查询,否则是评分查询。

过滤查询——Filtering queries

当使用于过滤情况时,查询被设置成一个“不评分”或者“过滤”查询。即这个查询只是简单的问一个问题:“这篇文档是否匹配?”。回答也是非常的简单,yes或者no ,二者必居其一。

过滤查询只是简单的检查包含或者排除,这就使得计算起来非常快,且结果会被缓存到内存中以便快速读取,所以有各种各样的手段来优化查询结果。

评分查询——scoring queries

当使用于查询情况时,查询就变成了一个“评分”的查询。和不评分的查询类似,也要去判断这个文档是否匹配,同时它还需要判断这个文档匹配的有多好(匹配程度如何)。

评分查询不仅仅要找出匹配的文档,还要计算每个匹配文档的相关性,计算相关性使得它们比不评分查询费力的多。同时查询结果并不缓存。

常用的查询方式

Elasticsearch自带了多种多样的查询方式,经使用到的有如下几种。

match_all

match_all查询简单的匹配所有文档。在没有指定查询方式时,它是默认的查询。

{
   "query":{
      "match_all":{}
   }
}

match

match查询用于针对文档中的某一个字段的匹配查询,匹配的条件可以是text/numerics/dates。

{
    "query": {
        "match" : {
            "message" : "test"
        }
    }
}

在使用match查询时常见的一种方式是将查询关键字用空格分开,例如keyword1 keyword2 keyword3,这时查询的结果是满足其中一个关键字的文档。即or的逻辑,如果有需要可以通过operator参数设置为and逻辑。

{
    "query": {
        "match": {
            "title": {
                "query": "lucene java",
                "operator": "and"
            }
        }
    }
}

在match查询中,可以设置fuzziness来指定查询的最大编辑数。例如:最大编辑数为2,说明query字符串中分词后,每个词允许编辑两次单个字符,可删除、新增、修改字符

{
    "query": {
        "match": {
            "title": {
                "query": "lucene java",
                "fuzziness": 2
            }
        }
    }
}

在match查询中,还可以使用minimum_should_match指定最少需要满足几个词匹配。

{
    "query": {
        "match": {
            "title": {
                "query": "ucen elatic java",
                "minimum_should_match": 2
            }
        }
    }
}

在match查询中,还可用max_expansions指定模糊匹配的最大词项数,默认是50。比如:反向索引中有100个词项与ucen模糊匹配,只选用前50 个。

{
    "query": {
        "match": {
            "title": {
                "query": "ucen",
                "max_expansions": 50
            }
        }
    }
}

multi_match

multi_match查询可以在多个字段上执行相同的match查询

{
    "query": {
        "multi_match": {
            "query":    "full text search",
            "fields":   [ "title", "body" ]
        }
    }
}

match_phrase

和match查询比较类似,但是它会保留包含所有搜索词项,且位置与搜索词项相同的文档。使用match_phrase还可以指定分词器(analyzer)

{
    "query": {
        "match_phrase" : {
            "message" : {
                "query" : "this is a test",
                "analyzer" : "my_analyzer"
            }
        }
    }
}

match_phrase_prefix

match_phrase_prefix 在 match_phrase 的基础上支持对短语的最后一个词进行前缀匹配

{
    "query": {
        "match_phrase_prefix" : {
            "message" : "quick brown f"
        }
    }
}

query_string

query_string 查询,让我们可以直接用lucene查询语法写一个查询串进行查询,ES中接到请求后,通过查询解析器解析查询串生成对应的查询。使用它要求掌握lucene的查询语法。

{
    "query": {
        "query_string" : {
            "default_field" : "content",
            "query" : "this AND that OR thus"
        }
    }
}

simple_query_string

simple_query_string 查同 query_string 查询一样用lucene查询语法写查询串,较query_string不同的地方:更小的语法集;查询串有错误,它会忽略错误的部分,不抛出错误。更适合给用户使用。

{
    "query": {
        "simple_query_string" : {
            "query": "\"fried eggs\" +(eggplant | potato) -frittata",
            "fields": ["title^5", "body"],
            "default_operator": "and"
        }
    }
}

term

term查询与match查询类似,区别在于term属于精确值匹配,这些精确值可能是text/numerics/dates。

{
    "query": {
        "term" : {
            "message" : "test"
        }
    }
}

terms

terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件

{
    "query": {
        "terms" : {
            "message" : [ "search", "full_text", "nosql" ]
        }
    }
}

range

range用于范围查询,使用range查询的字段必须是数字或者时间

range查询被允许的操作符如下:

配置项 描述
gt 大于
gte 大于等于
lt 小于
lte 小于等于
{
    "query": {
        "range" : {
            "gte":  20,
            "lt":   30
        }
    }
}

exits

查询指定字段值不为空的文档。相当SQL中的 column is not null

{
    "query": {
        "exists" : {
            "field" : "user"
        }
    }
}

missing

查询指定字段值为空的文档。相当SQL中的 column is null

{
    "query": {
        "missing" : {
            "field" : "user"
        }
    }
}

prefix

词项前缀查询

{
    "query": {
        "prefix" : {
            "user" : "ki"
        }
    }
}

wildcard

通配符查询

{
    "query": {
        "prefix" : {
            "user" : "ki*y"
        }
    }
}

regexp

正则查询

{
    "query": {
        "regexp":{
            "name": "s.*y"
        }
    }
}

ids

根据文档id查询

{
    "query": {
        "ids" : {
            "type" : "_doc",
            "values" : ["1", "4", "100"]
        }
    }
}

bool

bool查询用于将多查询组合在一起,成为用户自己想要的布尔查询

bool查询允许以下参数:

配置项 描述
must 文档必须匹配这些条件才能被包含进来。
must_not 文档必须不匹配这些条件才能被包含进来。
should 如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。
filter 必须匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。
{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "title": "how to make millions"
                }
            },
            "must_not": {
                "match": {
                    "tag":   "spam"
                }
            },
            "should": [
                {
                    "match": {
                        "tag": "starred"
                    }
                },
                {
                    "range": {
                        "date": {
                            "gte": "2014-01-01"
                        }
                    }
                }
            ]
        }
    }
}

constant_score

constant_score查询将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个filter而没有其它查询(例如,评分查询)的情况下。

可以使用它来取代只有filter语句的bool查询。在性能上是完全相同的,但对于提高查询简洁性和清晰度有很大帮助。

{
    "query": {
        "constant_score":   {
            "filter": {
                "term": {
                    "category": "ebooks"
                }
            }
        }
    }
}

参考资料

分类

开发
    --go (9)
    --java (5)
    --php (11)
    --mysql (9)
    --javascript (3)
    --html (1)
    --算法 (6)
架构
    --理论 (9)
    --网络 (3)
    --服务器 (2)
    --消息队列 (3)
    --容器 (5)
    --监控 (1)
    --搜索引擎 (3)
    --大数据 (0)
    --测试 (1)
系统
    --linux (10)
    --mac (2)
    --windows (1)
足球
    --世界杯 (60)
    --欧洲杯 (28)
    --文迷 (3)
大学时光
    --校园生活 (96)
    --假期生活 (17)
    --广院杯那些事 (14)
    --北京奥运 (6)
    --胡思乱写 (17)


最近发布

零拷贝技术介绍

服务网格技术简介

C语言标准和标准库简介

Kubernetes简介及环境搭建

Go语言开发的顶级项目


归档

2006 (109)
2007 (40)
2008 (47)
2009 (10)
2010 (6)
2012 (10)
2013 (14)
2014 (27)
2015 (15)
2016 (6)
2017 (8)
2018 (11)
2019 (17)
2020 (5)