ES 19 - Elasticsearch的检索语法(_search API的使用)

1 Search API的基本用法

1.1 查询全部数据

GET _search

1.2 响应信息说明

{
    "took" : 346,          // 整个检索消耗的时间, 单位是毫秒. 包括线程池中的等待时间、集群中分布式搜索+收集结果的时间
    "timed_out" : false,   // 默认不启用超时机制, 若启用, 须要设置具体的时间值
    "_shards" : {          // 搜索用到的shard数, 以及成功/失败的shard数
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0       // 一个Shard的Primary和Replicas都挂掉, 它才被认为失败
    },
    "hits" : {
        "total" : 10,      // 本次搜索命中(搜索到)的结果总数
        "max_score" : 1.0, // 本次搜索的全部结果中, 最大的相关度分数
        "hits" : [         // 默认显示查询结果中的前10条记录, 根据_score降序排序
            {
                "_index" : "book_shop",
                "_type" : "books",
                "_id" : "2",
                "_score" : 1.0,  // 相关度得分, 越相关, 分值越大, 排位越靠前
                "_source" : {
                    "name" : "Java编程思想",
                    "category" : "编程语言",
                    "author" : "Bruce Eckel",
                    "price" : 105.0,
                    "publisher" : "机械工业出版社",
                    "date" : "2016-01-01"
                }
            } 
        ]
    }
}

1.3 timeout超时机制

指定每一个Shard必须在规定的时间 (也就是指定的timeout时间) 内, 将搜索到的数据 (可能只搜索到了部分数据, 也可能搜索到了所有数据) 当即返回给客户端, 而不是等待查询操做彻底完成后再返回.html

—— 确保在指定时间内返回数据, 不管查询是否完成.java

ES的搜索默认不开启timeout, 查询持续的时间 (latency) 将根据查询的完整性 (completeness) 自动延迟, 能够手动指定timeout, 使用示例:shell

GET _search?timeout=10ms
# 可用的单位: timeout=10ms | timeout=1s | timeout=1m

举例说明:编程

Elasticsearch能在1分钟内查询到符合条件的所有2000条数据, 在指定timeout=10以后, 就会在10ms时返回查询到的部分结果, 此时可能只查询到了部分数据.json

1.4 查询多索引和多类型中的数据

(1) 一次性搜索多个索引(multi-index) 中的数据:api

# 搜索指定一个index下的全部数据
GET index1/_search

# 同时搜索两个index下的数据
GET index1,index2/_search

# 按照通配符匹配搜索多个index下的数据
GET *1,*2/_search

(2) 和多个类型(multi-type)在的数据:浏览器

注意事项: 在Elasticsearch 6.x以前的版本中, 支持一个index下有多个type, 在6.x以后的版本再也不支持.bash

# 搜索一个index下指定的type的数据
GET index1/type1/_search 

# 搜索一个index下多个type的数据
GET index1/type1,type2/_search 

# 搜索多个index下的多个type的数据
GET index1,index2/type1,type2/_search

# _all, 搜索全部index下指定type的数据
GET _all/type1,type2/_search

2 URI Search的用法

Elasticsearch支持经过在URI中携带请求参数执行搜索.并发

2.1 GET请求携带参数查询

好比要进行分页查询:

GET _search
{
    "from": 0,
    "size": 10
}

HTTP协议中通常不容许GET请求携带请求体 (Request Body), 但因为GET更加符合查询数据的操做, 所以能够携带Request Body. 而不少浏览器也都支持GET + Request Body模式.

若是遇到不支持GET + Request Body模式的场景, 也能够用POST方式查询, 好比:

POST _search
{
    "from":0,
    "size":10
}

或者使用拼接请求参数的方式进行查询:

GET _search?from=0&size=10

上述拼接的请求参数就是Query String, 这个串拼接的字段内容都是String, Elacticsearch底层会对各个field的类型进行映射.

2.2 URI Search的参数列表

参数 使用方法
q 查询字符串.
df 查询中没有定义前缀时, 默认的搜索字段.
analyzer 分析查询字符串所使用的分析器的名称.
lowercase_expanded_terms 搜索时忽略大小写标识, 默认为true.
analyze_wildcard 通配符或前缀查询是否被分析, 默认为false.
batched_reduce_size 协调节点须要减小的分片结果数. 当分片数量不少时, 会产生很大的内存开销, 这个参数用来当作保护机制.
default_operator 默认的多个条件之间的关系, 能够是 ANDOR. 默认是 OR.
lenient 若是设置为true, 字段类型转换失败时将忽略处理. 默认为false.
explain 在每一个返回结果中, 将包含评分机制的详细计算描述.
_source 是否包含元数据, 同时支持_source_incude_source_exclude.
stored_fields 选择查询到的文档的指定字段, 多个之间用","分隔. 若不指定任何字段, 就不会返回任何字段.
sort 根据字段名排序. 能够是fieldName, 或fieldName:desc, 或fieldName:asc, 或_score (给予分数的排序). 能够有多个排序参数, 要注意各参数之间的顺序.
track_scores 跟踪评分. 排序时, 设置为true后将跟踪评分状况, 并在返回的结果中携带评分信息.
track_total_hits 设置为false, 禁止跟踪每一个查询的结果总数. 默认为true, 即统计搜索到的结果总数.
timeout 搜索超时, 在指定的时间内执行搜索请求, 并在超时时间到期时返回查询到的已有结果. 默认无超时.
terminate_after 每一个分片搜索的最大文档数, 若是达到此值, 即便搜索还没有结束, 当前分片将提早终止搜索.
若是设置, 响应信息中将携带一个boolean类型的terminated_early字段, 表示查询提早终止了. 默认没有设置.
from 从全部返回结果中的第几条开始显示, 默认为0.
size 搜索结果返回的条数. 默认为10, 即返回前10条.
search_type 搜索的类型, 能够是dfs_query_then_fetchquery_then_fetch, 默认是query_then_fetch.
allow_partial_search_results 若是请求将产生部分结果, 设置为false用来返回总体故障. 默认为true, 这将在超时或部分失败的状况下, 返回部分结果.
能够经过集群中的search.default_allow_partial_results来设置此参数.

2.3 URI Search用法示例

// 查询索引index1中、类型为type一、field1=test的全部文档
GET index1/type1/_search?q=field1:test

// 查询索引index1中、类型为type一、必须知足field1=test的全部文档
GET index1/type1/_search?q=+test_field:test

// 查询索引index1中、类型为type一、不知足field1=test的全部文档
GET index1/type1/_search?q=-test_field:test

// 若是咱们只想知道是否存在与查询条件相匹配的文档, 而对文档的具体信息不感兴趣, 此时能够设置size=0.
// 还能够设置terminate_after=1, 指明只要在每一个shard中找到第一个匹配的文档, 就终止查询:
GET _search?q=field1:test&size=0&terminate_after=1

2.4 不指定field时的搜索原理

GET index1/type1/_search?q=test
// 一样, 可使用"+"或"-"来控制是否包含某个关键字, 好比: 查询不包含java的全部文档: 
GET shop/it_book/_search?q=-java

Elasticsearch默认为每一个文档配置了_all元字段, 将各个文档的全部field的值用字符串拼接起来, 这个长字符串就做为_all字段的值, 同时创建索引.

查询时, 若是不指定关键字所属的field, ES将从_all字段中搜索, 全部文档中只要存在field包含指定的关键字, 就算做匹配, 并将做为结果返回.

示例:

// 文档内容以下: 
{
    "name": "Java并发编程的艺术",
    "author": "方腾飞",
    "date": "2015-07",
    "publisher": "机械工业出版社"
}
// 搜索条件
GET shop/it_book/_search?q=java

// 该文档_all字段的值为: "Java并发编程的艺术 方腾飞 2015-07 机械工业出版社", _all字段中包含java, 因此可以匹配.

说明: 生产环境中不建议开启_all, 也不建议经过_all字段进行查询操做.

==> 在Elasticsearch 6.0版本中, _all字段已经被禁用了. 替代方案能够参考 这篇文章中的第3部分 .

版权声明

做者: 马瘦风

出处: 博客园 马瘦风的博客

感谢阅读, 若是文章有帮助或启发到你, 点个[好文要顶👆] 或 [推荐👍] 吧😜

本文版权归博主全部, 欢迎转载, 但 [必须在文章页面明显位置给出原文连接], 不然博主保留追究相关人员法律责任的权利.

相关文章
相关标签/搜索