Elasticsearch教程 — Search APIs
搜索 API 用于搜索和聚合存储在 Elasticsearch 索引和数据流中的数据。时ES的核心语法之一。
核心搜索
# 搜索
# <target>(可选,字符串)要搜索的数据流、索引和别名的逗号分隔列表。支持通配符(*)。要搜索所有数据流和索引,请省略此参数或使用*或_all。
# 查询参数、查询正文参数很多,参考文档
# https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
GET /<target>/_search
GET /_search
POST /<target>/_search
POST /_search
# 查询参数,URL的参数部分(重要的部分)
analyzer (可选,字符串)用于查询字符串的分析器。
default_operator (可选,字符串)查询字符串查询的默认运算符:AND 或 OR。默认为OR。
q (可选,字符串)以 Lucene 查询字符串语法进行查询。
search_type 搜索类型。分布式搜索操作需要分散到所有相关的分片,然后收集所有的结果。当使用分散/集合类型执行时,有几种方法可以做到这一点,特别是使用搜索引擎。
sort (可选,字符串)以逗号分隔的 <field>:<direction> 对列表。
# 查询正文,body部分(重要的部分)
fields、docvalue_fields (可选,字符串和对象数组)返回的字段,在响应的属性中返回与这些模式匹配的字段名称的值。
from (可选,整数)起始文档偏移量。默认为0。可用于分页。
size 可选,整数)要返回的结果数。默认为10。可用于分页。
explain (可选,布尔值)如果true,返回有关分数计算的详细信息作为命中的一部分。默认为false。
indices_boost 搜索多个索引时,可以提升某个或多个索引的权重。
min_score (可选,浮动)_score匹配文档的最小值。_score搜索结果中不包括具有较低值的文档。
query (可选,查询对象)使用Query DSL定义搜索定义。非常关键。
runtime_mappings 运行时字段,在运行搜索时创建的字段。
_source (可选)指示为匹配文档返回哪些源字段。
stats (可选,字符串数组)为其关联的搜索维护一个统计聚合。
timeout 超时,默认无超时。
version (可选,布尔值)如果true,则返回文档版本作为命中的一部分。
# 单个请求执行多个搜索
# <target>(可选,字符串)要搜索的数据流、索引和别名的逗号分隔列表。
# 查询的参数分两部分<header>与<body>两部分,参数同_search一样。
GET /<target>/_msearch
# 例子
GET my-index-000001/_msearch
{ }
{"query" : {"match" : { "message": "this is a test"}}} # 第一个查询
{"index": "my-index-000002"} # 第二个要查询的索引
{"query" : {"match_all" : {}}} # 第二个查询
# 异步搜索
POST /索引/_async_search?size=0
{
"sort": [
{ "date": { "order": "asc" } }
],
"aggs": {
"sale_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "1d"
}
}
}
}
# 搜索时间点(PIT、Point in time API)(这个api的keep_alive参数点在7.x版本中已经去除了)
# 滚动API(Scroll API) 就像使用快照一样,对其更改或后续添加数据不会影响原数据。
# 滚动不是用于实时用户请求,而是用于处理大量数据(甚至是全部数据,比如更适用于后台批处理任务)。
# 如果请求指定了聚合(aggregation),仅仅初始搜索响应才会包含聚合结果。
# 在url中设置 search_type=scan 可以关闭打分或者排序,让滚动更加高效。
GET /_search/scroll
POST /_search/scroll
# 创建Scroll示例,这里scroll=1m表示请求的结果"保持多长时间"
GET /<index>/_search?scroll=1m
{
"size": 10, # 分片,定义每次回传几条数据
"query": {
"match": {
"message": "foo"
}
}
}
# 在返回的结果中除了原有信息外,还包括一个_scroll_id参数。
{
"_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==", # 用以下次查询的参数
"took" : 1,
"timed_out" : false,
****
}
# 第一次或之后可以使用scroll_id来操作第一次返回的_scroll_id结果。
# 如果第二次请求再次带了scroll参数,此值会覆盖由原始搜索API请求的scroll参数设置的持续时间。
# 如果第二次请求不带上scroll参数,那么_scroll_id就会失效。
# 注意:因为有size参数的存在,每次返回size条数据,下次又依次返回下一页的size条数据,直到返回的hits中为空说明将数据全部返回了。
GET /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" # 上次请求返回的_scroll_id
}
# Scroll_id是有存在时间限制的,可以通过以下API查看
GET /_nodes/stats/indices/search
# 也可以使用命令清除Scroll_id,也可以批量清除或清除所有
DELETE /_search/scroll
{
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}
# Suggesters API(建议) 即在用户输入搜索的过程中,进行自动补全或者纠错。
# Suggesters基本的运作原理是将输入的文本分解为token(词元,分析器分析后的单词),然后在索引的字典里查找相似的term并返回。
# 根据使用场景的不同,Elasticsearch里设计了4种类别的Suggester
# Term Suggester(纠错补全,输入错误的情况下补全正确的单词)
# Phrase Suggester(自动补全短语,输入一个单词补全整个短语)
# Completion Suggester(完成补全单词,输出如前半部分,补全整个单词)
# Context Suggester(上下文补全)
POST /<index>/_search
{
"query" : { # 查询参数
"match": {
"message": "tring out Elasticsearch"
}
},
"suggest" : { # 建议参数
"my-suggestion" : { # 自定义建议名称
"text" : "tring out Elasticsearrrrch", # 被建议的字符串,注意这里写错了单词
"term" : { # Suggester的类型
"suggest_mode": "popular", # missing、popular、always
"field" : "message" # 字段名称
}
}
}
}
# 在返回的信息中
{
"took": 26,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": 0,
"hits": []
},
"suggest": {
"my-suggestion": [
{
"text": "elasticsearaach",
"offset": 0,
"length": 15,
"options": [ # 这里是返回的一些建议选项,如果为空就表示没建议,不为空就表示有建议
{
"text": "elasticsearch", # 建议的正确单词
"score": 0.84615386,
"freq": 3
}
]
}
]
}
}
搜索测试
# explain API 能够解释Document的Score是怎么得来的,具体每一部分的得分都可以详细地打印出来。
# <index> (必需,字符串)索引名称。
# <id> (必需,整数)定义文档ID。
# 返回的信息中的description字段介绍了公式算法,以及各种值的来源及描述。
GET /<index>/_explain/<id>
POST /<index>/_explain/<id>
# Profile API 帮用户进行性能分析,会提供有关搜索请求中各个组件执行的详细信息。输出非常详细,特别是对于跨多个分片的复杂请求执行。
GET /<index>/_search
{
"profile": true, # 开启性能分析,注意开启后非常耗费性能
"query" : {
"match" : { "message" : "GET /search" }
}
}
# 在返回的字段中会多返回一个profile字段
{
"profile" : {
"shards" : [ # 涉及一个或者多个碎片,每个分片都列出
{
"id" : "[Wh0K0xY0Q-apozD1V2fvNA][companies][0]", # 报告惟一的ID标识 [nodeID][indexName][shardID]
"searches" : [
{
"query" : [ # 显示查询的执行的详细分析内容
{
"type" : "TermQuery", # type字段显示Lucene类名
"description" : "search:公司", # description字段显示了查询的Lucene解释文本
"time_in_nanos" : 6331730, # time_in_nanos字段显示整个查询的花费(纳秒)
"breakdown" : {...} # 细分组件列出了底层Lucene执行的详细时间统计
}
],
"rewrite_time" : 5369, # 表示累计重写时间的时间
"collector" : [ # 关于运行搜索的Lucene收集器的分析
{
"name" : "SimpleTopScoreDocCollector",
"reason" : "search_top_hits", # 尝试给出收集器类名的简单英文描述
"time_in_nanos" : 4410144
}
]
}
],
"aggregations" : [ ] # 聚合分析的详细信息,不存在聚合就为空
}
]
}
}
# Field Capabilities API 允许您在多个索引中检索字段的功能。
GET /_field_caps?fields=<fields>
POST /_field_caps?fields=<fields>
GET /<target>/_field_caps?fields=<fields>
POST /<target>/_field_caps?fields=<fields>
# Ranking evaluation API 排名评估 API 允许您评估一组典型搜索查询的排名搜索结果的质量。
#
# 返回将针对其执行搜索请求的索引和分片。
GET /<target>/_search_shards
{
"nodes" : {
"Wh0K0xY0Q-apozD1V2fvNA" : {...},
"indices" : {
"companies" : { }
},
"shards" : [
[
{
"state" : "STARTED", # 分配状态
"primary" : true,
"node" : "Wh0K0xY0Q-apozD1V2fvNA", # 节点
"relocating_node" : null,
"shard" : 0, # 分片id
"index" : "companies", # 索引
"allocation_id" : {
"id" : "yr_FrKqWQhSMyNs2jtOLYw"
}
}
]
]
}
# Validates API(验证API) 验证一个潜在的昂贵的查询而不执行它。
# <target>(可选,字符串)要搜索的数据流、索引和别名
# query(可选,查询对象)使用Query DSL定义搜索定义
GET /<target>/_validate/<query>
GET /<index>/_validate/query
{
"query" : {
"bool" : {
"must" : {
"query_string" : {
"query" : "*:*"
}
},
"filter" : {
"term" : { "user.id" : "kimchy" }
}
}
}
}
# 如果查询是无效的,valid将是false。
搜索模板
# 创建或更新存储的脚本或 搜索模板。
# <script-id>(必需,字符串)存储脚本或搜索模板的标识符。在集群内必须是唯一的。
# <context>(可选,字符串)脚本或搜索模板应在其中运行的上下文。
PUT _scripts/<script-id>
POST _scripts/<script-id>
PUT _scripts/<script-id>/<context>
POST _scripts/<script-id>/<context>
# 删除储存脚本
DELETE _scripts/<script-id>
# 获取储存脚本或搜索模板信息
GET _scripts/<script-id>
# 使用示例,创建搜索模板
POST _scripts/my_search_template
{
"script": {
"lang": "mustache", # (必需,字符串) 脚本语言。对于搜索模板,请使用 mustache.
"params": {}, # (可选,对象)脚本或搜索模板的参数。
"source": { # (必需,字符串或对象)对于脚本,包含脚本的字符串。
"query": {
"match": {
"msg": "{{query_string}}"
}
}
}
}
}
# Search Template API(搜索模板) 使用搜索模板运行搜索。
# 搜索模板可让您在不修改应用程序代码的情况下更改搜索,也可以在不向用户公开Elasticsearch查询语法的情况下运行搜索。
# 使得搜索请求参数化,达到开发人员与搜索工程师解耦的效果。
GET <target>/_search/template
GET _search/template
POST <target>/_search/template
POST _search/template
# 参数source(必需*,对象)内联搜索模板。支持与搜索API的请求正文相同的参数。
GET <index>/_search/template
{
"id": "my-search-template", # 与source参数两个需有一个是必须。搜索模板的 ID。
"params": { #(可选,对象)用于替换模板中的 Mustache 变量的键值对。
"query_string": "hello world",
"from": 0,
"size": 10
}
}
# Render search template API(渲染搜索模板) 主要用来验证一个搜索模板与传入的数据。
# <template-id>(必需*,字符串)要呈现的搜索模板的 ID。如果没有source指定,则此或id请求正文参数是必需的。
# body参数与搜索模板一致。
GET _render/template
GET _render/template/<template-id>
POST _render/template
POST _render/template/<template-id>
地理空间搜索
# 搜索地理空间值
# <target>(必需,字符串)要搜索的数据流、索引或别名的逗号分隔列表
# <field>(必需,字符串)包含要返回的地理空间值的字段。必须是一个geo_point或geo_shape字段
# <zoom>(必需,整数)要搜索的矢量切片的缩放级别。接受0- 29
# <x> <y>(必需,整数)要搜索的矢量切片的X坐标,Y坐标
#
GET <target>/_mvt/<field>/<zoom>/<x>/<y>
POST <target>/_mvt/<field>/<zoom>/<x>/<y>
案例:ES提供的几种分页方法
具体的参考官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.16/paginate-search-results.html
注意:ES是分布式系统,查询数据时,会分别从每个分片查询后汇总到一起再返回。分页时size=10&from=990
虽然只返回10条,但是ES会从每个分片中查询1000条返回到一起,聚合后再取第990-1000这10条数据返回。所以,深度分页
(from很大时)通常在分布式系统中分页的效率会很低。
From + Size 查询
这个比较常规了
缺点:越往后的分页执行的效率越低,第一次查询与第二次查询的可能导致重复。
优点:支持随机翻页
Scroll 查询
参考上面提到的Scroll分页。不过ES官方文档中不推荐采取这种方式进行深度分页。官方建议深度分页采用Search After方式。
Search After 查询
search_after查询本质:使用前一页中的一组排序值来检索匹配的下一页。在第一次请求时,必须加上sort字段,返回第一页列表的最后值的sort字段,下一次请求时携带search_after参数,此参数使用上一次请求携带的sort值。
search_after缺点:是不能够随机跳转
分页,只能是一页一页的向后翻
,并且需要至少指定一个唯一不重复
字段来排序。
search_after优点:适合深度分页,
# 第一页请求示例
GET twitter/_search
{
"size": 2,
"query": {
"match": {
"city": "北京"
}
},
"sort": [ # 必须要携带这个参数,因为携带这个参数才会在结果中返回这个参数
{"DOB":{"order": "asc"}},
{"user.keyword": {"order": "asc"}}
]
}
# 第一页请求结果
{
"took" : 29,
"timed_out" : false,
"_shards" : {
"total" : 1
},
"hits" : {
"hits" : [
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "2",
"_score" : null,
"_source" : {
},
"sort" : [ # 这里返回的是最后一条数据的sort参数
347155200000,
"东城区-老刘"
]
}
]
}
}
# 下一页请求示例
GET twitter/_search
{
"size": 2,
"from": 0, # 当我们使用search_after时,from值必须设置为0
"query": {
"match": {
"city": "北京"
}
},
"search_after": [ # 这里使用上一页请求的最后数据
347155200000,
"东城区-老刘"
],
"sort": [ # 必须要携带这个参数,因为携带这个参数才会在结果中返回这个参数
{"DOB":{"order": "asc"}},
{"user.keyword": {"order": "asc"}}
]
}
最后更新于 2021-12-02 09:50:20 并被添加「Elasticsearch教程」标签,已有 1311 位童鞋阅读过。
本站使用「署名 4.0 国际」创作共享协议,可自由转载、引用,但需署名作者且注明文章出处
此处评论已关闭