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使用from和size参数进行分页。
- 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"
}
}
}
}
}
参考资料
- https://www.cnblogs.com/Neeo/articles/10576402.html
- https://blog.csdn.net/supermao1013/article/details/84192965
- https://blog.csdn.net/supermao1013/article/details/84261526
- https://www.elastic.co/guide/cn/elasticsearch/guide/current/query-dsl-intro.html
- https://www.elastic.co/guide/cn/elasticsearch/guide/current/_queries_and_filters.html
- https://www.elastic.co/guide/cn/elasticsearch/guide/current/_most_important_queries.html -https://www.elastic.co/guide/cn/elasticsearch/guide/current/combining-queries-together.html