GlobalOrdinalsStringTermsAggregator$LeafBucketCollector.col
本文以TermQuery,GlobalOrdinalsStringTermsAggregator为例,,通过代码,分析es,lucene搜索及聚合流程。
1:协调治点收到请求后,将search任务发到相关的各个shard。
相关代码:
TransportSearchAction.executeSearch TransportSearchAction.searchAsyncAction.start AbstractSearchAsyncAction.executePhase(SearchQueryThenFetchAsyncAction) InitialSearchPhase.performPhaseOnShard SearchQueryThenFetchAsyncAction.executePhaseOnShard
2:数据节点盘问及聚合一个shard。
相关代码:
SearchService.executeQueryPhase
2.1:按照request结构SearchContext。
SearchContext
包罗Query,Aggregator等重要信息。并将记录盘问,聚合功效。
Query
按照request创建具体的query,如:
TermQuery:用于keyword,text字段。索引布局为倒排。
PointRangeQuery:用于数字,日期,ip,point等字段。索引布局为k-d tree。
Aggregator
此时仅按照request创建AggregatorFactory,用于后续创建Aggregator。
相关代码:
SearchService.createAndPutContext
2.2:按照SearchContext结构Aggregator。
按照SearchContext结构具体的Aggregator,如:
GlobalOrdinalsStringTermsAggregator:用于keyword字段,开启global ordinal的term聚合。
StringTermsAggregator:用于keyword字段,封锁global ordinal的term聚合。
LongTermsAggregator:用于long字段的term聚合。
TopScoreDocCollector:用于为doc 评分并取topN。
相关代码:
AggregationPhase.preProcess
2.3:创建GlobalOrdinalsStringTermsAggregator,如果cache中没有GlobalOrdinals,将创建GlobalOrdinals,并cache。当shard下数据产生变革时,该当清空cache。
GlobalOrdinals
将所有segment ,指定field的所有term排序,合并成一个GlobalOrdinals,并创建OrdinalMap。collect时,使用doc的segment ord获取global ord。
OrdinalMap
为每一个segmentValueCount小于globalValueCount的segment,生存了一份segment ord到global ord的mapping(LongValues)。对付segment valueCount即是globalValueCount的segment,原本的segment ord就是global ord,后续获取ord时,直接从SortedSetDV(dvd)中读取。
value count
指的是差别term数量(term调集的巨细)。使用globalValueCount 用来在collect时,确定功效集的巨细。
举例
segment 1:{sorted terms: [aa, bb, cc],ord:[0, 1, 2]}。
segment 2:{sorted terms: [bb, cc, dd],ord:[0, 1, 2]}。
segment 3:{sorted terms: [aa, bb, cc, dd],ord:[0, 1, 2, 3]}。
GlobalOrdinals:{sorted terms: [aa, bb, cc, dd],ord:[0, 1, 2, 3]}。
ordinalMap:segment1:[0, 1, 2]->[0, 1, 2],segment2:[0, 1, 2]->[1, 2, 3]。segment3则使用原始的segment ord。
docCounts
int[globalValueCount],用来记录ord对应的count。
注:经盘问条件过滤后,有些ord可能没有对应doc。
bucketOrds
稀疏(value count多,但doc少)时使用,缩减docCounts size。
LongHash:globalOrd与 id (size)映射。collect时在id处++,build agg时取出id对应的count。
当父聚合是BucketAggregator聚合时,子聚合只对父的某个term聚合,所以doc会减少,使用bucketOrds。
注:凭据此逻辑,如果query自己有term过滤条件,也应该启用bucketOrds(global_ordinals_hash)。
相关代码:
TermsAggregatorFactory.doCreateInternal。 //获取globalValueCount决定是否global_ordinals_low_cardinality, global_ordinals_low_cardinality中又因不是ValuesSource.Bytes.FieldData,创建global_ordinals。 ValuesSource$WithOrdinals.globalMaxOrd。 //通过获取一个segment的globalOrdinals,触发如果cache中没有一个shardId+field对应的globalOrdinals,load 所有segment ord,成立global ords。 ValuesSource$FieldData.globalOrdinalsValues。 SortedSetDVOrdinalsIndexFieldData.loadGlobal。 IndicesFieldDataCache$IndexFieldCache.load SortedSetDVOrdinalsIndexFieldData.localGlobalDirect。 GlobalOrdinalsBuilder.build。 //globalOrdinals主要类 GlobalOrdinalsIndexFieldData。 MultiDocValues$OrdinalMap
2.3.1:从docValues中读取单个segment,指定field的ordinals,term等。
相关代码:
SortedSetDVOrdinalsIndexFieldData.load。 SortedSetDVBytesAtomicFieldData.getOrdinalsValues。 //获取segment指定field的SortedSetDocValues DocValues.getSortedSet。 //获取segment的docValuesReader SegmentReader.getDocValuesReader。 //读取field的SortedDocValues Lucene54DocValuesProducer.getSortedSet。
2.3.2:对多个segment的SortedSetDocValues排序,创建OrdinalMap。
具体为获取每个segment的SortedDocValuesTermsEnum。使用多个SortedDocValuesTermsEnum构建成小顶堆,合并成一个。
相关代码:
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/31702.html
- 上一篇: 我们来看以上代码
- 下一篇:配置时最好将被依赖的模块放前面 办法2、不添加直接引用关系