简介

说明

        本文介绍ElasticSearch如何通过Rest API(URL)来查询数据。

Elasticsearch有两种查询方式

  • URI带有查询条件(轻量查询)
  • 查询能力有限,只适合比较简单的查询。
  • 请求体中带有查询条件(复杂查询) 
  • 查询条件以JSON格式表现,作为查询请求的请求体,适合复杂的查询 。

官网

Search API | Elasticsearch Reference [7.15] | Elastic

url查询 

请求参数位于_search端点之后,参数之间使用&分割,例如:

GET /_search?pretty&q=title:azure&explain=true&from=1&size=10&sort=title:asc&fields:user,title,content

端点

        查询端点允许RESTful API或客户端查询ElasticSearch引擎中存储的数据,通过HTTP动词定义操作,通过URI定位数据资源。

1,用于搜索数据的端点

查询ElasticSearch引擎,主要使用_search 和_query端点,_search端点允许执行搜索查询,返回查询结果。在_search端点上,能够执行RESTful API查询和Qeury DSL查询,例如一下脚本:

GET /_search?q=user:kimchy
GET /_search -d
{
    "query" : {
        "term" : { "user" : "kimchy" }
    }
}

ElasticSearch的所有查询请求都发送到_search端点,对于_query端点,只用于将查询的结果删除:DELETE /_query?q=user:kimchy

2,分析端点(_analyze)

分析端点_analyze,用于对查询参数进行分析,并返回分析的结果:POST /_analyze?field=title -d

3,计数端点(_count)

在计数端点_count上,执行查询,获取满足查询条件的文档数量:GET /_count?q=user:jim

4,解释端点(_explain)

用于验证指定的文档是否满足查询条件,格式是index/type/_id/_explain,例如

GET index/type/1/_explain?q=message:search

空索引

其他网址

空搜索 | Elasticsearch: 权威指南 | Elastic

        搜索API的最基础的形式是没有指定任何查询的空搜索,它简单地返回集群中所有索引下的所有文档。

命令

GET /_search

返回结果

{
   "hits" : {
      "total" :       14,
      "hits" : [
        {
          "_index":   "us",
          "_type":    "tweet",
          "_id":      "7",
          "_score":   1,
          "_source": {
             "date":    "2014-09-17",
             "name":    "John Smith",
             "tweet":   "The Query DSL is really powerful and flexible",
             "user_id": 2
          }
       },
        ... 9 RESULTS REMOVED ...
      ],
      "max_score" :   1
   },
   "took" :           4,
   "_shards" : {
      "failed" :      0,
      "successful" :  10,
      "total" :       10
   },
   "timed_out" :      false
}

结果含义如下

hits

        返回结果中最重要的部分是 hits ,它包含 total 字段来表示匹配到的文档总数,并且一个 hits 数组包含所查询结果的前十个文档。

        在 hits 数组中每个结果包含文档的 _index 、 _type 、 _id ,加上 _source 字段。这意味着我们可以直接从返回的搜索结果中使用整个文档。这不像其他的搜索引擎,仅仅返回文档的ID,需要你单独去获取文档。

        每个结果还有一个 _score ,它衡量了文档与查询的匹配程度。默认情况下,首先返回最相关的文档结果,就是说,返回的文档是按照 _score 降序排列的。在这个例子中,我们没有指定任何查询,故所有的文档具有相同的相关性,因此对所有的结果而言 1 是中性的 _score 。

max_score

        与查询所匹配文档的 _score 的最大值。

took

        took 值告诉我们执行整个搜索请求耗费了多少毫秒。

shards

        _shards 部分告诉我们在查询中参与分片的总数,以及这些分片成功了多少个失败了多少个。正常情况下我们不希望分片失败,但是分片失败是可能发生的。如果我们遭遇到一种灾难级别的故障,在这个故障中丢失了相同分片的原始数据和副本,那么对这个分片将没有可用副本来对搜索请求作出响应。假若这样,Elasticsearch 将报告这个分片是失败的,但是会继续返回剩余分片的结果。

timeout

        timed_out 值告诉我们查询是否超时。默认情况下,搜索请求不会超时。如果低响应时间比完成结果更重要,你可以指定 timeout 为 10 或者 10ms(10毫秒),或者 1s(1秒):GET /_search?timeout=10ms
        在请求超时之前,Elasticsearch 将会返回已经成功从每个分片获取的结果。

        应当注意的是 timeout 不是停止执行查询,它仅仅是告知正在协调的节点返回到目前为止收集的结果并且关闭连接。在后台,其他的分片可能仍在执行查询即使是结果已经被发送了。

        使用超时是因为 SLA(服务等级协议)对你是很重要的,而不是因为想去中止长时间运行的查询。

多索引/类型

其他网址

多索引,多类型 | Elasticsearch: 权威指南 | Elastic

如果不对某一特殊的索引或者类型做限制,就会搜索集群中的所有文档。Elasticsearch 转发搜索请求到每一个主分片或者副本分片,汇集查询出的前10个结果,并且返回给我们。

然而,经常的情况下,你想在一个或多个特殊的索引并且在一个或者多个特殊的类型中进行搜索。我们可以通过在URL中指定特殊的索引和类型达到这种效果,如下所示:

url

作用

/_search

在所有的索引中搜索所有的类型

/gb/_search

在 gb 索引中搜索所有的类型

/gb,us/_search

在 gb 和 us 索引中搜索所有的文档

/g*,u*/_search

在任何以 g 或者 u 开头的索引中搜索所有的类型

/gb/user/_search

在 gb 索引中搜索 user 类型

/gb,us/user,tweet/_search

在 gb 和 us 索引中搜索 user 和 tweet 类型

/_all/user,tweet/_search

在所有的索引中搜索 user 和 tweet 类型

        当在单一的索引下进行搜索的时候,Elasticsearch 转发请求到索引的每个分片中,可以是主分片也可以是副本分片,然后从每个分片中收集结果。多索引搜索恰好也是用相同的方式工作的—只是会涉及到更多的分片。

        搜索一个索引有五个主分片和搜索五个索引各有一个分片准确来所说是等价的。

参数

大全

官网:Search API | Elasticsearch Reference [7.10] | Elastic

参数名

参数值描述

q

查询字符串。

sort

根据指定字段进行排序,可以存在多个sort(顺序很重要)。

示例:sort=field1:asc,field:desc

from

第一个文档的起始位置。默认是0。

示例:from=10&size=15

size

结果的数量。默认是10.

df

查询字符串中未指定字段时所使用的默认字段。

analyzer

分析查询字符串时使用的分析器

analyze_wildcard

是否分析通配符查询或前缀查询,默认为false。

default_operator

默认多个条件的关系。AND或OR,默认为OR

lenient

格式转换错误是否被忽略。默认为false

_source

查询结果是否包含_source字段。

stored_fields

查询结果包含的字段,使用逗号分隔

track_scores

查询结果中是否包含score数据

track_total_hits

查询结果中是否包含total数据

timeout

查询超时时间

terminate_after

每个分片收集文档的上限值,当文档超过上限时会终止查询,并在查询结果中terminated_early表示是否超过上限。

search_type

查询类型,可以是dfs_query_then_fetch或query_then_fetch。默认为query_then_fetch

示例

url

作用

GET blog/_search?q=active

查询所有字段中包含active的文档。按_score排序

GET blog/_search?q=status:active

查询status字段中包含active的文档。按_score排序

GET blog/_search?q=status:"active"

查询status字段中包含active的文档。只返回最高_score项

GET blog/_search?q=book.\*:(quick brown)

根据book.title、book.content等字段中的内容进行查询,返回字段中包含quick或brown的文档。

GET blog/_search?q=title:(quick OR brown)
GET blog/_search?q=title:(quick brown)

根据title字段中的内容进行查询,返回字段中包含quick或brown的文档。默认操作符为OR

GET blog/_search?q=_exists_:title

根据title字段中的内容进行查询,返回字段不未空的文档。

GET blog/_search?q=title:(a* b?)

    根据title字段中的内容进行查询,返回字段中包含以a开头或以b开头的文档。通配符*标识匹配0个或多个字符,通配符?标识1个字符。
    通配符会影响查询效率,会消耗过多的内存。以通配符开头的查询,会匹配索引中所有的文档,不建议使用。

GET blog/_search?q=name:/joh?n(ath[oa]n)/

根据name字段中的内容进行查询,返回字段中匹配//中正则表达式的文档。

GET blog/_search?q=name:quikc~

根据name字段中的内容进行查询,返回字段中模糊匹配quikc的文档。模糊匹配的字符最多有2处与quikc不同,包括多字符、少字符、错位。

GET blog/_search?q=count:[1 TO 5}
GET blog/_search?q=count:(+>=1 +<5)

根据count字段中的内容进行查询,返回字段中大于等于1并小于5的文档。

GET blog/_search?q=title:(quick^2 fox)

根据title字段中的内容进行查询,返回字段中包含quick或fox的文档。quick文档相关性更高

GET blog/_search?q=title:(quick brown +fox -news)

根据title字段中的内容进行查询,返回字段中一定包含fox并不包含news的文档。quick brown可有可无,如果存在评分会更高。

通用选项

其他网址

常见选项 - elasticsearch

官网

Common options | Elasticsearch Reference [7.10] | Elasticpicking-up-a-new-property | Elasticsearch Reference [7.10] | Elastic

说明

以下选项可以应用于所有 REST APIs 。 

Pretty Results(优雅的结果)

pretty=true

返回的 JSON 将优雅地格式化(仅用于调试!)

format=yaml

这将使结果以(有时)更可读的 yaml 格式返回。

Date Math

大多数接收格式化日期值的参数(例如,gt 和 lt)在范围内查询范围查询,或者从 date range 聚合中获取或者理解 date math 。

表达式

表达式以 anchor date( 锚定日期) 开始,可以是现在,也可以是以 || 结尾的 date 字符串。此锚定日期可以选择性地后跟一个或多个 maths。

数学表达式

含义

+1h

add one hour (  加一个小时 )

-1d

subtract one day ( 减去一天 )

/d

round down to the nearest day ( 向下舍入到最近的一天 )

支持的time units( 时间单位)

不同于持续时间支持的时间单位。所支持的单位是:

符号

含义

y

years

M

months

w

weeks

d

days

h

hours

H

hours

m

minutes

s

seconds

示例

表达式

含义

now+1h

当前时间加上一个小时,以毫秒(ms)为单位

now+1h+1m

当前时间加上一个小时一分钟,以毫秒(ms)为单位

now+1h/d

当前时间加上一个小时,向下舍入到最近的一天。

2015-01-01||+1M/d

2015-01-01 加一个月,向下舍入到最近一天。

respoonse filtering( 响应过滤)

filter_path

减少 elasticsearch 返回的响应参数。此参数采用用点表示法表示的以逗号分隔的过滤器列表:GET /_search?q=elasticsearch&filter_path=took,hits.hits._id,hits.hits._score

Responds( 响应):

{
    "took" : 3,
    "hits" : {
        "hits" : [
            {
                "_id" : "0",
                "_score" : 1.6375021
            }
        ]
    }
}

通配符

“**”通配符可以用于包括不知道确切路径的字段

例如,我们可以返回带有此请求的每个 segment( 段) 的 Lucene** 版本:GET /_cluster/state?filter_path=routing_table.indices.**.state

Responds( 响应) :

{
    "routing_table": {
        "indices": {
            "twitter": {
                "shards": {
                    "0": [{"state": "STARTED"}, {"state": "UNASSIGNED"}],
                    "1": [{"state": "STARTED"}, {"state": "UNASSIGNED"}],
                    "2": [{"state": "STARTED"}, {"state": "UNASSIGNED"}],
                    "3": [{"state": "STARTED"}, {"state": "UNASSIGNED"}],
                    "4": [{"state": "STARTED"}, {"state": "UNASSIGNED"}]
                }
            }
        }
    }
}

“-”前缀过滤器排除一个或多个字段

GET /_count?filter_path=-_shards

Responds( 响应) :

{
    "count" : 5
}

组合过滤器

为了更多的控制,inclusive( 包含) 和 exclusive( 独占过滤器) 可以组合在同一个表达式。在这种情况下,将首先应用 exclusive filters( 独占过滤器) ,并使用 inclusive filters( 包含过滤器)再次过滤效果:

GET /_cluster/state?filter_path=metadata.indices.*.state,-metadata.indices.logstash-*

Responds( 响应) :

{
    "metadata" : {
        "indices" : {
            "index-1" : {"state" : "open"},
            "index-2" : {"state" : "open"},
            "index-3" : {"state" : "open"}
        }
    }
}

请注意, elasticsearch 有时直接返回字段的原始值,如 _source 字段。如果要过滤 _source 字段,应该考虑将已有的 source 参数(请参阅 Get API 了解更多详细信息 )与 filterpath 参数组合,如下所示:

POST /library/book?refresh
{"title": "Book #1", "rating": 200.1}
POST /library/book?refresh
{"title": "Book #2", "rating": 1.7}
POST /library/book?refresh
{"title": "Book #3", "rating": 0.1}

GET /_search?filter_path=hits.hits._source&_source=title&sort=rating:desc

GET /_search?filter_path=hits.hits._source&_source=title&sort=rating:desc
{
    "hits" : {
        "hits" : [ {
                "_source":{"title":"Book #1"}
            }, {
                "_source":{"title":"Book #2"}
            }, {
                "_source":{"title":"Book #3"}
        } ]
    }
}

Flat Settings(平面设置) 

flat_settings 标志影响设置列表的呈现。默认flat_settings 为 false 。

当 flat_settings 标志为 true 时,设置以平面格式返回:

GET twitter/_settings?flat_settings=true

Returns( 返回) :

{
    "twitter" : {
        "settings": {
            "index.number_of_replicas": "1",
            "index.number_of_shards": "1",
            "index.creation_date": "1474389951325",
            "index.uuid": "n6gzFZTgS664GUfx0Xrpjw",
            "index.version.created": ...,
            "index.provided_name" : "twitter"
        }
    }
}

当 flat_settings 标志为 false 时,设置以更易于阅读的结构化格式返回:

Returns( 返回) :

{
    "twitter" : {
        "settings" : {
            "index" : {
                    "number_of_replicas": "1",
                    "number_of_shards": "1",
                    "creation_date": "1474389951325",
                    "uuid": "n6gzFZTgS664GUfx0Xrpjw",
                    "version": {
                    "created": ...
                },
                "provided_name" : "twitter"
            }
        }
    }
}

Time units(时间单位)

每当需要指定持续时间时,对于 timeout 参数,持续时间必须指定单位,如 2d 为 2天。支持的单位有:

符号

含义

d

days

h

hours

m

minutes

s

seconds

ms

milliseconds

micros

microseconds

nanos

nanoseconds

byte size units(字节大小单位)

每当需要指定数据的字节大小时,例如,当设置 buffer(缓冲区) 大小参数时,该值必须指定单位,例如 10 千字节的 10kb 。支持的单位有:

单位

全称

b

Bytes

kb

Kilobytes

mb

Megabytes

gb

Gigabytes

tb

Terabytes

pb

Petabytes

unit-less quantities(无单位数量)

        无单位数量意味着它们没有像“ bytes(字节) ”或者“ Hertz(赫兹) ”或者“ meter(米) ”或者“ long tonne(长吨) ” 的“单位”。

        如果这些数量中的一个很大,我们将打印出来,如10,000万的 10m 或者 7,000 的 7k 。如果项打印 87,仍然打印 87 , 。这些是支持的 multipliers(乘数) :

符号

含义

``

Single

k

Kilo

m

Mega

g

Giga

t

Tera

p

Peta

distance units(距离单位)

无论在何处需要指定距离,例如“地理距离查询”中的距离参数,默认单位(如果没有指定)是 meter(米) 。距离可以用其他单位指定,例如 “1公里(km)”或者“2英里(mi)”。

单位的完整列表如下:

单位

表示符号

Mile

mi 或者 miles

Yard

yd 或者 yards

Feet

ft 或者 feet

Inch

in 或者 inch

Kilometer

km 或者 kilometers

Meter

m 或者 meters

Centimeter

cm 或者 centimeters

Millimeter

mm 或者 millimeters

Nautical mile

NM, nmi 或者 nauticalmiles

Enabling stack traces(启用堆栈跟踪)

默认情况下,当请求返回错误时,Elasticsearch 不包括错误的堆栈跟踪。您可以将 error_trace_url 参数设置为 true 来启用该行为。

例如,默认情况下,当您向 _search API 发送无效的 size 参数时:POST /twitter/_search?size=surprise_me

响应看起来像下面这样:

{
    "error" : {
        "root_cause" : [
            {
                "type" : "illegal_argument_exception",
                "reason" : "Failed to parse int parameter [size] with value [surprise_me]"
            }
        ],
        "type" : "illegal_argument_exception",
        "reason" : "Failed to parse int parameter [size] with value [surprise_me]",
        "caused_by" : {
            "type" : "number_format_exception",
            "reason" : "For input string: \"surprise_me\""
        }
    },
    "status" : 400
}

但是,如果设置 error_trace=true : POST /twitter/_search?size=surprise_me&error_trace=true

响应看起来像这样:

{
    "error": {
        "root_cause": [
            {
            "type": "illegal_argument_exception",
            "reason": "Failed to parse int parameter [size] with value [surprise_me]",
            "stack_trace": "Failed to parse int parameter [size] with value [surprise_me]]; nested: IllegalArgumentException..."
            }
        ],
        "type": "illegal_argument_exception",
        "reason": "Failed to parse int parameter [size] with value [surprise_me]",
        "stack_trace": "java.lang.IllegalArgumentException: Failed to parse int parameter [size] with value [surprise_me]\nat org.elasticsearch.rest.RestRequest.paramAsInt(RestRequest.java:175)...",
        "caused_by": {
            "type": "number_format_exception",
            "reason": "For input string: \"surprise_me\"",
            "stack_trace": "java.lang.NumberFormatException: For input string: \"surprise_me\"\nat java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)..."
        }
    },
    "status": 400
}

request body in query string(在查询字符串中的请求主体)

对于不接受非 POST 请求的请求主体的库,您可以将请求正文作为源查询字符串参数传递。使用此方法时,source_content_type 参数也应该传递一个 media type value ,该值指示 source 的格式,例如application/json 。

警告:Deprecated in 5.3.0.(在5.3.0中弃用)。

Provide the proper Content-Type header(提供适当的 Content-Type 标题)

检查在 request body 中发送的内容或使用 source query string parameter 来自动确定内容类型 (JSON,YAML,SMILE 或 CBOR)。

可以启用 strict mode(严格模式) ,禁用 auto-detection(自动检测功能),并要求所有具有 body 的请求都具有映射到支持格式的 Content-Type header 。要启用此 strict mode(严格模式),请将以下设置添加到 elasticsearch.yml 文件中:

http.content_type.required: true        //默认值为 false 。

其他

Fuzziness(模糊性)

一些查询和 APIs 支持参数以允许使用模糊性参数进行不精确的模糊匹配。

当查询 text(文本) 或者 keyword fields(关键字字段)时,模糊性被解释为 Levenshtein Edit Distance —— 是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。

Human readable output(人类可读的输出)

human=true

作用:以适合人类的格式(例如 "exists_time":"1h" 或者 "size":"1kb")和计算机(例如 "exists_time_in_millis":"3600000" 或者 "size_in_bytes":"1024")返回统计信息。

human 的标识的默认值是 false (关闭人类可读的值)。当统计结果被监视工具消费而不是用于人类消费时,这将是有意义的。

Parameters(参数)

Rest 参数(当使用 HTTP 时,映射到 HTTP URL 参数)遵循使用下划线框的惯例。

Boolean Values(布尔值)

所有 REST APIs 参数(请求参数和 JSON 正文)支持提供布尔值 "false" 作为值: false, 0, no 和 off 。所有其他值均被视为 "true" 。

警告:Deprecated in 5.3.0.( 在5.3.0中弃用。)不推荐使用 "false" 和 "true" 以外的任何值。

Number Values(数值)

所有 REST APIs 支持将编号的参数作为 string( 字符串) 提供,以支持本机 JSON 数字类型。