@@ -640,6 +640,53 @@ func (i *indexImpl) SearchInContext(ctx context.Context, req *SearchRequest) (sr
640640 }
641641 }
642642
643+ // ------------------------------------------------------------------------------------------
644+ // set up additional contexts for any search operation that will proceed from
645+ // here, such as presearch, knn collector, topn collector etc.
646+
647+ // Scoring model callback to be used to get scoring model
648+ scoringModelCallback := func () string {
649+ if isBM25Enabled (i .m ) {
650+ return index .BM25Scoring
651+ }
652+ return index .DefaultScoringModel
653+ }
654+ ctx = context .WithValue (ctx , search .GetScoringModelCallbackKey ,
655+ search .GetScoringModelCallbackFn (scoringModelCallback ))
656+
657+ // This callback and variable handles the tracking of bytes read
658+ // 1. as part of creation of tfr and its Next() calls which is
659+ // accounted by invoking this callback when the TFR is closed.
660+ // 2. the docvalues portion (accounted in collector) and the retrieval
661+ // of stored fields bytes (by LoadAndHighlightFields)
662+ var totalSearchCost uint64
663+ sendBytesRead := func (bytesRead uint64 ) {
664+ totalSearchCost += bytesRead
665+ }
666+
667+ ctx = context .WithValue (ctx , search .SearchIOStatsCallbackKey , search .SearchIOStatsCallbackFunc (sendBytesRead ))
668+
669+ // Geo buffer pool callback to be used for getting geo buffer pool
670+ var bufPool * s2.GeoBufferPool
671+ getBufferPool := func () * s2.GeoBufferPool {
672+ if bufPool == nil {
673+ bufPool = s2 .NewGeoBufferPool (search .MaxGeoBufPoolSize , search .MinGeoBufPoolSize )
674+ }
675+
676+ return bufPool
677+ }
678+
679+ ctx = context .WithValue (ctx , search .GeoBufferPoolCallbackKey , search .GeoBufferPoolCallbackFunc (getBufferPool ))
680+
681+ // check if the index mapping has any nested fields, which should force
682+ // all collectors and searchers to be run in nested mode
683+ if nm , ok := i .m .(mapping.NestedMapping ); ok {
684+ if nm .CountNested () > 0 {
685+ ctx = context .WithValue (ctx , search .NestedSearchKey , true )
686+ }
687+ }
688+ // ------------------------------------------------------------------------------------------
689+
643690 if _ , ok := ctx .Value (search .PreSearchKey ).(bool ); ok {
644691 preSearchResult , err := i .preSearch (ctx , req , indexReader )
645692 if err != nil {
@@ -666,7 +713,7 @@ func (i *indexImpl) SearchInContext(ctx context.Context, req *SearchRequest) (sr
666713 req .SearchBefore = nil
667714 }
668715
669- coll , err := i .buildTopNCollector (req , indexReader )
716+ coll , err := i .buildTopNCollector (ctx , req , indexReader )
670717 if err != nil {
671718 return nil , err
672719 }
@@ -749,44 +796,12 @@ func (i *indexImpl) SearchInContext(ctx context.Context, req *SearchRequest) (sr
749796 ctx = context .WithValue (ctx , search .FieldTermSynonymMapKey , fts )
750797 }
751798
752- scoringModelCallback := func () string {
753- if isBM25Enabled (i .m ) {
754- return index .BM25Scoring
755- }
756- return index .DefaultScoringModel
757- }
758- ctx = context .WithValue (ctx , search .GetScoringModelCallbackKey ,
759- search .GetScoringModelCallbackFn (scoringModelCallback ))
760-
761799 // set the bm25Stats (stats important for consistent scoring) in
762800 // the context object
763801 if bm25Stats != nil {
764802 ctx = context .WithValue (ctx , search .BM25StatsKey , bm25Stats )
765803 }
766804
767- // This callback and variable handles the tracking of bytes read
768- // 1. as part of creation of tfr and its Next() calls which is
769- // accounted by invoking this callback when the TFR is closed.
770- // 2. the docvalues portion (accounted in collector) and the retrieval
771- // of stored fields bytes (by LoadAndHighlightFields)
772- var totalSearchCost uint64
773- sendBytesRead := func (bytesRead uint64 ) {
774- totalSearchCost += bytesRead
775- }
776-
777- ctx = context .WithValue (ctx , search .SearchIOStatsCallbackKey , search .SearchIOStatsCallbackFunc (sendBytesRead ))
778-
779- var bufPool * s2.GeoBufferPool
780- getBufferPool := func () * s2.GeoBufferPool {
781- if bufPool == nil {
782- bufPool = s2 .NewGeoBufferPool (search .MaxGeoBufPoolSize , search .MinGeoBufPoolSize )
783- }
784-
785- return bufPool
786- }
787-
788- ctx = context .WithValue (ctx , search .GeoBufferPoolCallbackKey , search .GeoBufferPoolCallbackFunc (getBufferPool ))
789-
790805 searcher , err := req .Query .Searcher (ctx , indexReader , i .m , search.SearcherOptions {
791806 Explain : req .Explain ,
792807 IncludeTermVectors : req .IncludeLocations || req .Highlight != nil ,
@@ -1435,7 +1450,7 @@ func (i *indexImpl) FireIndexEvent() {
14351450 }
14361451}
14371452
1438- func (i * indexImpl ) buildTopNCollector (req * SearchRequest , reader index.IndexReader ) (* collector.TopNCollector , error ) {
1453+ func (i * indexImpl ) buildTopNCollector (ctx context. Context , req * SearchRequest , reader index.IndexReader ) (* collector.TopNCollector , error ) {
14391454 newCollector := func () * collector.TopNCollector {
14401455 if req .SearchAfter != nil {
14411456 return collector .NewTopNCollectorAfter (req .Size , req .Sort , req .SearchAfter )
@@ -1450,18 +1465,18 @@ func (i *indexImpl) buildTopNCollector(req *SearchRequest, reader index.IndexRea
14501465 return collector .NewNestedTopNCollector (req .Size , req .From , req .Sort , nr )
14511466 }
14521467
1453- if nm , ok := i . m .(mapping. NestedMapping ); ok {
1454- if nm . CountNested () > 0 {
1455- if nr , ok := reader .(index. NestedReader ); ok {
1456- var fs search. FieldSet
1457- var err error
1458- fs , err = query . ExtractFields ( req . Query , i . m , fs )
1459- if err != nil {
1460- return nil , err
1461- }
1462- if nm . IntersectsPrefix ( fs ) {
1463- return newNestedCollector ( nr ), nil
1464- }
1468+ // check if we are in nested mode
1469+ if nestedMode , ok := ctx . Value ( search . NestedSearchKey ).( bool ); ok && nestedMode {
1470+ // get the nested reader from the index reader
1471+ if nr , ok := reader .(index. NestedReader ); ok {
1472+ var fs search. FieldSet
1473+ var err error
1474+ fs , err = query . ExtractFields ( req . Query , i . m , fs )
1475+ if err != nil {
1476+ return nil , err
1477+ }
1478+ if nm . IntersectsPrefix ( fs ) {
1479+ return newNestedCollector ( nr ), nil
14651480 }
14661481 }
14671482 }
0 commit comments