1 搜索所有数据
timeout参数:是超时时长定义。代表每个节点上的每个shard执行搜索时最多耗时多久。不会影响响应的正常返回。只会影响返回响应中的数据数量。
如:索引a中,有10亿数据。存储在5个shard中,假设每个shard中2亿数据,执行全数据搜索的时候,需要耗时1000毫秒。定义timeout为10毫秒,代表的是shard执行10毫秒,搜索出多少数据,直接返回。
语法:
GET _search?timeout=10ms
结果:
{
"took": 144, #请求耗时多少毫秒
"timed_out": false, #是否超时。默认情况下没有超时机制,也就是客户端等待ES搜索结束(无论执行多久),提供超时机制的话,ES则在指定时长内处理搜索,在指定时长结束的时候,将搜索的结果直接返回(无论是否搜索结束)。指定超时的方式是传递参数,参数单位是:毫秒-ms。秒-s。分钟-m。
"_shards": {
"total": 1, #请求发送到多少个shard上
"successful": 1,#成功返回搜索结果的shard
"skipped": 0, #停止服务的shard
"failed": 0 #失败的shard
},
"hits": {
"total": 1, #返回了多少结果
"max_score": 1, #搜索结果中,最大的相关度分数,相关度越大分数越高,_score越大,排位越靠前。
"hits": [ #搜索到的结果集合,默认查询前10条数据。
{
"_index": "test_index", #数据所在索引
"_type": "my_type", #数据所在类型
"_id": "1", #数据的id
"_score": 1, #数据的搜索相关度分数
"_source": { # 数据的具体内容。
"field": "value"
}
}
]
}
}
2 _all应用1
_all也是ES中的一个内置元数据。也可以成为内置变量名。代表全部的意思。一般来说_all使用的很少。
语法:
GET /_all/_search
这种_all的用法相当于在所有的索引中搜索数据。也就是_all代表所有的索引。
3 multi-index搜索模式
所谓的multi-index就是从多个index中搜索数据。相对使用较少,只有在复合数据搜索的时候,可能出现。一般来说,如果真使用复合数据搜索,都会使用_all。
如:搜索引擎中的无条件搜索。(现在的应用中都被屏蔽了。使用的是默认搜索条件,执行数据搜索。 如: 电商中的搜索框默认值, 搜索引擎中的类别)
无条件搜索,在搜索应用中称为“魔鬼搜索”,代表的是,搜索引擎会执行全数据检索,效率极低,且对资源有非常高的压力。
语法:
GET _search GET /index_name1,index_name2/_search # 搜索多个index中的数据 GET /index_name/type_name1/_search # 所属一个index中type的数据 GET /prefix_*/_search # 通配符搜索
GET /*_suffix/_search GET /index_name1,index_name2/type_name1/_search # 搜索多个index中type的数据 GET /_all/_search # _all代表所有的索引
4 分页搜索
语法:
GET /_search?size=10 # size查询数据的行数 GET /_search?from=0&size=10 # from 从第几行开始查询,行号从0开始。
4.1 deep paging问题
什么是deep paging?
就是搜索深度,如数据有100万,分页要求每页50条数据,总计2万页,现在搜索第1000页,执行的搜索语句就是: GET /_search?from=49999&size=50。执行的时候,请求发送到协调节点中,协调节点将搜索请求发送给所有的节点,而数据可能分部在多个节点中,那么搜索过程就很麻烦了。过程是集群中的每个节点将节点内符合要求的数据返回给协调节点,协调节点再将所有节点返回的数据根据默认排序条件(_score)排序,并筛选最终符合要求的数据返回给客户端。
这个搜索的过程对协调节点的压力太高。尽量避免出现deep paging操作。
上述案例解释:集群有4个节点,每个节点有1个分片(primary shard),每个分片中有数据25万。请求发起,命令为GET /_search?from=49999&size=50。协调节点将请求发给所有的节点,所有的节点分别查询第50000~50050条数据,ES的分页实际上是伪分页,每个节点返回的数据是0~50050条数据。协调节点得到的数据是50050*4条数据。协调节点实现排序,再找出50000~50050的50条数据,再返回。
5 +/-搜索
语法:
GET /products_index/phone_type/_search?q=name:plus GET /products_index/phone_type/_search?q=+name:plus GET /products_index/phone_type/_search?q=-name:plus
+ :和不定义符号含义一样,就是搜索指定的字段中包含key words的数据
- : 与+符号含义相反,就是搜索指定的字段中不包含key words的数据
6 _all应用2
如:电商平台中,搜索手机,问,是搜索商品名中包含手机的商品?还是搜索商品卖点中包含手机的商品?还是搜索商品详情描述中包含手机的商品?
在ES中,可以直接提供一个搜索关键字,不提供搜索的字段名。默认是再全字段数据中搜索关键字内容。
在ES中,每保存一个document,都会将document中所有的field拼接到一起,保存为一个命名为_all的字段。这个_all字段,就是默认搜索的字段。
_all是一个默认使用的搜索数据存储单元,不是一个可以指明使用的字段命名。
语法:
GET /index_name/type_name/_search?q=key_words
这种搜索代表索引中的Document中,任意的一个field包含key_words都会被搜索到。执行命令的时候,ES底层是使用_all元数据搜索的。在ES维护Document的时候,会将Document中的所有字段数据作为一个_all元数据执行的field。如:
Document数据是{ "name" : "zhangsan", "age" : 20, "email" : "zhangsan@163.com" },在ES保存Document的时候,会额外维护一个_all字段,字段数据为"zhangsan 20 zhangsan@163.com"。那么在搜索的时候,不指定要搜索匹配的field,ES就从_all元数据中匹配key_words。
不推荐生产环境中使用,因为数据越复杂,搜索效率越低。