目录
1.简介
Elasticsearch真正强大之处在于可以从混乱的数据中找出有意义的信息——从大数据到全面的信息。
为什么我们使用结构化的JSON文档,而不是无结构的二进制数据?
Elasticsearch不只会存储(store)文档,也会索引(indexes)文档内容来使之可以被搜索。
每个文档里的字段都会被索引并被查询。
在简单查询时,Elasticsearch可以使用所有的索引,以非常快的速度返回结果。
概念 | 解释 |
映射(Mapping) | 数据在每个字段中的解释说明 |
分析(Analysis) | 全文是如何处理的可以被搜索的 |
领域特定语言查询(Query DSL) | Elasticsearch使用的灵活的、强大的查询语言 |
1.1.空搜索
最基本的搜索API表单是空搜索(empty search),它没有指定任何的查询条件,只返回集群索引中的所有文档
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
包含了 total 字段来表示匹配到的文档总数
hits 数组包含了匹配到的前10条数据。
hits 数组中的每个结果都包含 _index 、_type 和文档的 _id 字段,被加入到 _source 字段中这意味着在搜索结果中将直接使用全部文档。
每个节点都有一个 _score 字段,这是相关性得分(relevance score),它衡量了文档与查询的匹配程度。
默认的,返回的结果中关联性最大的文档排在首位;它是按照 _score 降序排列的。
这种情况下,我们没有指定任何查询,所以所有文档的相关性是一样的,因此所有结果的 _score 都是取得一个中间值 1
max_score 指的是所有文档匹配查询中 _score 的最大值。
took
整个搜索请求花费的毫秒数
shards
_shards,参与查询的分片数( total 字段),有多少是成功的( successful 字段),有多少的是失败的( failed 字段)。
timeout
time_out,查询超时与否。一般的,搜索请求不会超时。如果响应速度比完整的结果更重要,可以定义 timeout 参数为 10 或者 10ms (10毫秒),或者 1s (1秒)
GET /_search?timeout=10ms
警告
需要注意的是 timeout 不会停止执行查询,它仅仅告诉你目前顺利返回结果的节点然后关闭连接。
在后台,其他分片可能依旧执行查询,尽管结果已经被发送。
使用超时是因为对于你的业务需求(译者注:SLA,Service-Level Agreement服务等级
协议,在此我翻译为业务需求)来说非常重要,而不是因为你想中断执行长时间运行的查询。
1.2.多索引和多类别
可以在集群中跨所有文档搜索。
Elasticsearch转发搜索请求到集群中平行的主分片或每个分片的复制分片上,收集结果后选择顶部十个返回。
【举例】
/_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 中搜索 search types user and tweet in all indices
当搜索包含单一索引时,Elasticsearch转发搜索请求到这个索引的主分片或每个分片的复制分片上,然后聚集每个分片的结果。
搜索包含多个索引也是同样的方式——只不过或有更多的分片被关联。
重要
搜索一个索引有5个主分片和5个索引各有一个分片事实上是一样的。
1.3.分页
Elasticsearch接受 from 和 size 参数:
size : 结果数,默认 10
from : 跳过开始的结果数,默认 0
【举例】
每页显示5个结果,页码从1到3
GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
在集群系统中深度分页
假设在一个有5个主分片的索引中搜索。
当请求结果的第一页(结果1到10)时,每个分片产生自己最顶端10个结果然后返回它们给请求节点(requesting node),
它再排序这所有的50个结果以选出顶端的10个结果。
假设我们请求第1000页——结果10001到10010。
工作方式都相同,不同的是每个分片都必须产生顶端的10010个结果。
然后请求节点排序这50050个结果并丢弃50040个!
在分布式系统中,排序结果的花费随着分页的深入而成倍增长。
这也是为什么网络搜索引擎中任何语句不能返回多于1000个结果的原因。
TIP
如何能高效的检索大量文档
1.4.简易搜索
search API有两种表单:
一种是“简易版”的查询字符串(query string)将所有参数通过查询字符串定义;
另一种版本使用JSON完整的表示请求体(request body),这种富搜索语言叫做结构化查询语句(DSL);
查询字符串搜索对于在命令行下运行点对点(ad hoc)查询特别有用。
【举例】
GET /_all/tweet/_search?q=tweet:elasticsearch
+name:john +tweet:mary
"+" 前缀表示语句匹配条件必须被满足。
"-" 前缀表示条件必须不被满足。
_all 字段
返回包含 "mary" 字符的所有文档的简单搜索
GET /_search?q=mary
_all field
name 字段包含 "mary" 或 "john"
date 晚于 2014-09-10
_all 字段包含 "aggregations" 或 "geo"
+name:(mary john) +date:>2014-09-10 +(aggregations geo)
编码后的查询字符串变得不太容易阅读:
?q=%2Bname%3A(mary+john)+%2Bdate%3A%3E2014-09-10+%2B(aggregations+geo)