ES-索引查询机制(三)

ES查询可以分为两大类,一类是Get,一类是Search,下面说一下Es内部是怎么实现的.

一:Get检索

通过ID检索特定的Doc

> 查询的时候是先查询内存中的TransLog,如果找到就立即返回
> 如果没找到再查询磁盘上的TransLog
> 如果还没有则再去查询磁盘上的Segment(原始Lucene)

二:Search检索

通过query查询来匹配对应的Doc文档,查询的时候是一起查询内存和磁盘上的Segment,最后将结果合并后返回

。其实它有三个对应的实现,默认使用的是第二个,第三个评分准确度最高,但是性能也是最低的,实际使用中需要根据具体的业务需求,选择对应的检索阶段。

1 query_and_fetch:第一阶段查询到匹配的DocID
2 query_then_fetch:第二阶段再查询DocID对应的完整文档
3 dfs_query_then_fetch:先收集所有Shard中的TF和DF值,然后将这些值带入请求中,再次执行query_then_fetch,这样算分的时候TF和DF就是准确的

三:检索具体流程

> 实现机制概括

第一阶段的Query Phase请求,则会调用SearchService的executeQueryPhase方法

第二阶段的Fetch Phase请求,则会调用SearchService的executeFetchPhase方法

> 具体步骤

ClientNode:客户端节点

Get Remote Cluster Shard:判断是否需要跨集群访问,如果需要,则获取到要访问的Shard列表。

Get Search Shard Iterator:获取当前Cluster中要访问的Shard,勾出要访问完整的shard列表

For Every Shard:Perform:遍历每个Shard,对每个Shard执行后面逻辑

Send Request To Query Shard:将查询阶段请求发送给相应的Shard

Merge Docs:
>> 异步等待返回结果,然后对结果合并
	维护一个Top N大小的优先级队列,每当收到一个shard的返回,就把结果放入优先级队列做一次排序,直到所有的Shard都返回。
>>分页查询
	search_after
		返回的总数据量只是和Shard个数以及本次需要的个数有关,和历史已读取的个数无关
	深度分页
		通过scroll来实现
			本质类似于游标
			不能逆行查询,往返查询
				只能查询下一页

QueryPhase:一阶段查询

Query Phase
	1 Create Search Context
		创建Search Context,之后Search过程中的所有中间状态都会存在Context中
	 2 Parse Query
		解析Query的Source,将结果存入Search Context
	3 Get From Cache
		判断请求是否允许被Cache,如果允许,则检查Cache中是否已经有结果
	4 Add Collectors
		收集查询结果,实现排序,自定义结果集过滤和收集等
			FilteredCollector
				先判断请求中是否有Post Filter,Post Filter用于Search,Agg等结束后再次对结果做Filter,希望Filter不影响Agg结果。如果有Post Filter则创建一个FilteredCollector,加入Collector List中。
			PluginInMultiCollector
				判断请求中是否制定了自定义的一些Collector,如果有,则加入Collector List。
			MinimumScoreCollector
				:判断请求中是否制定了最小分数阈值,如果指定了,则创建MinimumScoreCollector加入Collector List中,在后续收集结果时,会过滤掉得分小于最小分数的Doc
			EarlyTerminatingCollector
				判断请求中是否提前结束Doc的Seek,如果是则创建EarlyTerminatingCollector,加入Collector List中。在后续Seek和收集Doc的过程中,当Seek的Doc数达到Early Terminating后会停止Seek后续倒排链
			CancellableCollector
				判断请求中是否提前结束Doc的Seek,如果是则创建EarlyTerminatingCollector,加入Collector List中。在后续Seek和收集Doc的过程中,当Seek的Doc数达到Early Terminating后会停止Seek后续倒排链
	5 lucene::search
		调用Lucene中IndexSearch的search接口,执行真正的搜索逻辑
	6 rescore
		根据Request中是否包含rescore配置决定是否进行二阶段排序,如果有则执行二阶段算分逻辑,会考虑更多的算分因子
	7 suggest::execute()
		如果有推荐请求,则在这里执行推荐请求
	8 aggregation::execute()
		如果含有聚合统计请求,则在这里执行

FetchPhase:二阶段查询

Fetch Phase
	当Client Node选择出最终Top N的结果后,再对最终的Top N读取Doc内容
		ExplainFetchSubPhase
		DocValueFieldsFetchSubPhase
		ScriptFieldsFetchSubPhase
		FetchSourceSubPhase
		VersionFetchSubPhase
		MatchedQueriesFetchSubPhase
		HighlightPhase
		ParentFieldSubFetchPhase
	通过插件的形式注册自定义的功能

> 牵涉核心类

SearchPhase
	AggregationPhase
		聚合查询
	DfsPhase
		三阶段查询
	FetchPhase
		二阶段查询
	QueryPhase
		一阶段查询
	RescorePhase
		二次加分查询
	SuggestPhase
		推荐查询

备注:es查询 默认没有实现保证全局精准的TF-IDF

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章