Elasticsearch查询(Windows)
简单查询:curl -XGET lcoalhost:9200/megacorp/employee/_search?pretty
注意:
响应内容不仅会告诉我们哪些文档被匹配到,而且这些文档内容完整的被包含在其中—我们在给用户展示搜索结果时
需要用到的所有信息都有了
等同于
GET /_search
{
"query": {
"match_all": {}
}
}
hits
响应中最重要的部分是 hits ,它包含了 total 字段来表示匹配到的文档总数, hits 数组还包含了匹配到的前10条数据。
hits 数组中的每个结果都包含 _index 、 _type 和文档的 _id 字段,被加入到 _source 字段中这意味着在搜索结果中我们将
可以直接使用全部文档。这不像其他搜索引擎只返回文档ID,需要你单独去获取文档。
每个节点都有一个 _score 字段,这是相关性得分(relevance score),它衡量了文档与查询的匹配程度。默认的,返回的结
果中关联性最大的文档排在首位;这意味着,它是按照 _score 降序排列的。这种情况下,我们没有指定任何查询,所以所有
文档的相关性是一样的,因此所有结果的 _score 都是取得一个中间值 1
max_score 指的是所有文档匹配查询中 _score 的最大值。
took
took 告诉我们整个搜索请求花费的毫秒数。
shards
_shards 节点告诉我们参与查询的分片数( total 字段),有多少是成功的( successful 字段),有多少的是失败的
( failed 字段)。通常我们不希望分片失败,不过这个有可能发生。如果我们遭受一些重大的故障导致主分片和复制分片都
故障,那这个分片的数据将无法响应给搜索请求。这种情况下,Elasticsearch将报告分片 failed ,但仍将继续返回剩余分片上的结果
timeout
time_out 值告诉我们查询超时与否。一般的,搜索请求不会超时。如果响应速度比完整的结果更重要,你可以定
义 timeout 参数为 10 或者 10ms (10毫秒),或者 1s (1秒)
GET /_search?timeout=10ms
Elasticsearch将返回在请求超时前收集到的结果。
超时不是一个断路器(circuit breaker)(译者注:关于断路器的理解请看警告)。
警告:需要注意的是 timeout 不会停止执行查询,它仅仅告诉你目前顺利返回结果的节点然后关闭连接。在后台,其他分片
可能依旧执行查询,尽管结果已经被发送。
使用超时是因为对于你的业务需求(译者注:SLA,Service-Level Agreement服务等级协议,在此我翻译为业务需
求)来说非常重要,而不是因为你想中断执行长时间运行的查询。
DSL(Domain specific Language)JSON请求体的形式出现
curl -XGET localhost:9200/megacorp/employee/_search?pretty -d{\"query\":{\"match\":{\"name\":\"John\"}}}
查找名字为John 年龄大于18岁的员工:
curl -XGET localhost:9200/megacorp/employee/_search?pretty -d{\"query
\":{\"filtered\":{\"filter\":{\"range\":{\"age\":{\"gt\":30}}},
\"query\":{\"match\":{\"name\":\"John\"}}}}}
添加了一个过滤器(filter)用于执行区间搜索
<1> 这部分查询属于区间过滤器(range filter),它用于查找所有年龄大于18岁的数据—— gt 为"greater than"的缩写。
<2> 这部分查询与之前的 match 语句(query)一致。
到目前为止搜索都很简单:搜索特定的名字,通过年龄筛选。让我们尝试一种更高级的搜索,全文搜索——一种传统数据库
很难实现的功能。
我们将会搜索所有喜欢“rock climbing”的员工:
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
全文你可以看到我们使用了之前的 match 查询,从 about 字段中搜索"rock climbing",我们得到了两个匹配文档:
<1><2> 结果相关性评分。
默认情况下,Elasticsearch根据结果相关性评分来对结果集进行排序,所谓的「结果相关性评分」就是文档与查询条件的匹
配程度。很显然,排名第一的 John Smith 的 about 字段明确的写到“rock climbing”。
但是为什么 Jane Smith 也会出现在结果里呢?原因是“rock”在她的 abuot 字段中被提及了。因为只有“rock”被提及
而“climbing”没有,所以她的 _score 要低于John。
这个例子很好的解释了Elasticsearch如何在各种文本字段中进行全文搜索,并且返回相关性最大的结果集。相关性
(relevance)的概念在Elasticsearch中非常重要,而这个概念在传统关系型数据库中是不可想象的,因为传统数据库对记录的查询只有匹配或者不匹配。
短语搜索
目前我们可以在字段中搜索单独的一个词,这挺好的,但是有时候你想要确切的匹配若干个单词或者短语(phrases)。例如我
们想要查询同时包含"rock"和"climbing"(并且是相邻的)的员工记录。
要做到这个,我们只要将 match 查询变更为 match_phrase 查询即ke
高亮我们的搜索
很多应用喜欢从每个搜索结果中高亮(highlight)匹配到的关键字,这样用户可以知道为什么这些文档和查询相匹配。在
Elasticsearch中高亮片段是非常容易的。
让我们在之前的语句上增加 highlight 参数:
聚合(aggregations)
允许在数据上生成复杂的分析统计。它很像SQL中的GROUP BY但是功能更强大
检索多个文档
multi-get或者 mget API
mget API参数是一个 docs 数组,数组的每个节点定义一个文档的 _index 、 _type 、 _id 元数据。如果你只想检索一个或几
个确定的字段,也可以定义一个 _source 参数:
GET /_mget
{
"docs" : [
{
"_index" : "website",
"_type" : "blog",
"_id" : 2
},
{
"_index" : "website",
"_type" : "pageviews",
"_id" : 1,
"_source": "views"
}
]
}
如果你想检索的文档在同一个 _index 中(甚至在同一个 _type 中),你就可以在URL中定义一个默认的 /_index 或
者 /_index/_type 。
你依旧可以在单独的请求中使用这些值:
GET /website/blog/_mget
{
"docs" : [
{ "_id" : 2 },
{ "_type" : "pageviews", "_id" : 1 }
]
}
事实上,如果所有文档具有相同 _index 和 _type ,你可以通过简单的 ids 数组来代替完整的 docs 数组:
GET /website/blog/_mget
{
"ids" : [ "2", "1" ]
}
注意:
尽管前面提到有一个文档没有被找到,但HTTP请求状态码还是 200 。事实上,就算所有文档都找不到,请求也还是返
回 200 ,原因是 mget 请求本身成功了。如果想知道每个文档是否都成功了,你需要检查 found 标志。
更省时的批量操作
bulk API允许我们使用单一请求来实现多个文档
的 create 、 index 、 update 或 delete 。这对索引类似于日志活动这样的数据流非常有用,它们可以以成百上千的数据为一
个批次按序进行索引。
bulk 请求体如下,它有一点不同寻常:
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
...
这种格式类似于用 "\n" 符号连接起来的一行一行的JSON文档流(stream)。两个重要的点需要注意:
每行必须以 "\n" 符号结尾,包括最后一行。这些都是作为每行有效的分离而做的标记。
每一行的数据不能包含未被转义的换行符,它们会干扰分析——这意味着JSON不能被美化打印。
整个批量请求最佳大小开始的数量可以在
1000~5000个文档之间,如果你的文档非常大,可以使用较小的批次。
通常着眼于你请求批次的物理大小是非常有用的。一千个1kB的文档和一千个1MB的文档大不相同。一个好的批次最好保持
在5-15MB大小间。