Elasticsearch系列---初识搜索
概要
本篇主要介绍搜索的报文结构含义、搜索超时时间的处理过程,提及了一下多索引搜索和轻量搜索,最后将精确搜索与全文搜索做了简单的对比。
空搜索
搜索API最简单的形式是不指定索引和类型的空搜索,它将返回集群下所有索引的所有文档(默认显示10条):
GET /_search
响应的结果示例(有筛选,只取了一条document作为示例):
{ "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 3, "max_score": 1, "hits": [ { "_index": "music", "_type": "children", "_id": "2", "_score": 1, "_source": { "name": "wake me, shark me", "content": "don't let me sleep too late, gonna get up brightly early in the morning", "language": "english", "length": "55", "likes": 9 } } ] } }
针对响应报文的字段,我们做一些简单解释:
- took:整个搜索请求花费了多少毫秒。
- time_out:查询是否超时。
- _shards:查询中参与分片的总数,其中成功的分片数量,失败的分片数量,以及跳过的分片数量。正常情况下不会有失败的分片数量,如果发生了灾难级别的故障,超过了容错的最大node数量,可能会同时丢失shard和replica,此时会报告这些分片是失败的,但还是会继续返回剩余可用分片的查询结果。
- hits:包含total表示匹配到的文档总数,max_score值是所有匹配文档中_score的最大值。
- hits.hits:数组内包含匹配的文档的完整信息,默认查询前10条数据,并且按_score降序排序。
timeout机制
默认不使用timeout参数,如果某些场景下,低响应比搜索完整结果更重要,可以指定timeout为10ms或1s,在指定的超时时间内,Elasticsearch会把已经成功搜索到的文档返回。
注意timeout不是停止执行查询,它只是告诉Coordinate Node返回到指定时间为止收集到的结果,并且关闭连接,在ES后台,其他node正在进行的查询并不会中断,只是结果没人要了。
举个例子:某电商平台商品SKU品类300万条,输入某个关键字查询,有2000条记录匹配,但是要查15秒钟,一个搜索要等15秒才出结果,显得太不专业了,产品有SLA要求,必须1秒内出结果,最快的解决方案是查询使用参数timeout=1s,前端分页显示默认只展示20条,1秒内的查询结果要填满这20条还是比较容易的。
多索引搜索
一个搜索请求,可以同时写多个索引名称,这叫做multi-index搜索模式。
/_search:所有索引,所有type下的所有数据都搜索出来
/index1,index2/_search:同时搜索两个index下的数据
/1,2/_search:按照通配符去匹配多个索引
单一索引下搜索时,ES会转发请求到索引的每个分片中,shard或replica均可,然后收集结果返回。多索引时,原理相同,只是涉及的分片更多。另外搜索一个索引有5个分片和搜索5个索引各有一个分片,性能是等价的。
顺带我们看一下搜索原理示意图:
轻量搜索
有两种形式的搜索API,一种是query string search,查询条件和排序规则写在request URI里,也叫轻量搜索;另一种是query DSL,查询条件等信息用JSON格式写在request body里。
轻量搜索的示例:
单个字段搜索,"q="后面接的是查询条件"field:text",field是字段名,text是搜索的关键词,有三种前缀修饰符:
GET /music/children/_search?q=content:friend GET /music/children/_search?q=+content:friend GET /music/children/_search?q=-content:friend
- "+"号前缀表示必须与查询条件匹配。
- "-"号前缀表示一定不与查询条件匹配。
- 默认没写前缀表示条件可选
匹配的条件越多,文档就越相关。
如果多个字段搜索,多个条件之间要有空格:
GET /music/children/_search?q=-content:friend +name:wake
_all元数据的原理
如果"q="后面没写field,直接跟的是搜索关键词,表示搜索指定索引下的所有字段,如下: