Java Code Examples for org.apache.lucene.search.Scorer#iterator()

The following examples show how to use org.apache.lucene.search.Scorer#iterator() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: LuceneBatchIterator.java    From crate with Apache License 2.0 6 votes vote down vote up
private boolean tryAdvanceDocIdSetIterator() throws IOException {
    if (currentDocIdSetIt != null) {
        return true;
    }
    while (leavesIt.hasNext()) {
        LeafReaderContext leaf = leavesIt.next();
        Scorer scorer = weight.scorer(leaf);
        if (scorer == null) {
            continue;
        }
        currentScorer = scorer;
        currentLeaf = leaf;
        currentDocIdSetIt = scorer.iterator();
        for (LuceneCollectorExpression<?> expression : expressions) {
            expression.setScorer(currentScorer);
            expression.setNextReader(currentLeaf);
        }
        return true;
    }
    return false;
}
 
Example 2
Source File: GlobalOrdinalsWithScoreQuery.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
  SortedDocValues values = DocValues.getSorted(context.reader(), joinField);
  if (values == null) {
    return null;
  }

  Scorer approximationScorer = in.scorer(context);
  if (approximationScorer == null) {
    return null;
  } else if (globalOrds != null) {
    return new OrdinalMapScorer(this, collector, values, approximationScorer.iterator(), globalOrds.getGlobalOrds(context.ord));
  } else {
    return new SegmentOrdinalScorer(this, collector, values, approximationScorer.iterator());
  }
}
 
Example 3
Source File: GlobalOrdinalsQuery.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
  SortedDocValues values = DocValues.getSorted(context.reader(), joinField);
  if (values == null) {
    return null;
  }

  Scorer approximationScorer = approximationWeight.scorer(context);
  if (approximationScorer == null) {
    return null;
  }
  if (globalOrds != null) {
    return new OrdinalMapScorer(this, score(), foundOrds, values, approximationScorer.iterator(), globalOrds.getGlobalOrds(context.ord));
  } {
    return new SegmentOrdinalScorer(this, score(), foundOrds, values, approximationScorer.iterator());
  }
}
 
Example 4
Source File: ToParentBlockJoinQuery.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
public BlockJoinScorer(Weight weight, Scorer childScorer, BitSet parentBits, ScoreMode scoreMode) {
  super(weight);
  //System.out.println("Q.init firstChildDoc=" + firstChildDoc);
  this.parentBits = parentBits;
  this.childScorer = childScorer;
  this.scoreMode = scoreMode;
  childTwoPhase = childScorer.twoPhaseIterator();
  if (childTwoPhase == null) {
    childApproximation = childScorer.iterator();
    parentApproximation = new ParentApproximation(childApproximation, parentBits);
    parentTwoPhase = null;
  } else {
    childApproximation = childTwoPhase.approximation();
    parentApproximation = new ParentApproximation(childTwoPhase.approximation(), parentBits);
    parentTwoPhase = new ParentTwoPhase(parentApproximation, childTwoPhase);
  }
}
 
Example 5
Source File: BlockGroupingCollector.java    From lucene-solr with Apache License 2.0 6 votes vote down vote up
@Override
protected void doSetNextReader(LeafReaderContext readerContext) throws IOException {
  if (subDocUpto != 0) {
    processGroup();
  }
  subDocUpto = 0;
  docBase = readerContext.docBase;
  //System.out.println("setNextReader base=" + docBase + " r=" + readerContext.reader);
  Scorer s = lastDocPerGroup.scorer(readerContext);
  if (s == null) {
    lastDocPerGroupBits = null;
  } else {
    lastDocPerGroupBits = s.iterator();
  }
  groupEndDocID = -1;

  currentReaderContext = readerContext;
  for (int i=0; i<comparators.length; i++) {
    leafComparators[i] = comparators[i].getLeafComparator(readerContext);
  }
}
 
Example 6
Source File: GroupingLongCollectorBenchmark.java    From crate with Apache License 2.0 6 votes vote down vote up
@Benchmark
public LongObjectHashMap<Long> measureGroupingOnNumericDocValues() throws Exception {
    Weight weight = searcher.createWeight(new MatchAllDocsQuery(), ScoreMode.COMPLETE_NO_SCORES, 1.0f);
    LeafReaderContext leaf = searcher.getTopReaderContext().leaves().get(0);
    Scorer scorer = weight.scorer(leaf);
    NumericDocValues docValues = DocValues.getNumeric(leaf.reader(), "x");
    DocIdSetIterator docIt = scorer.iterator();
    LongObjectHashMap<Long> sumByKey = new LongObjectHashMap<>();
    for (int docId = docIt.nextDoc(); docId != DocIdSetIterator.NO_MORE_DOCS; docId = docIt.nextDoc()) {
        if (docValues.advanceExact(docId)) {
            long number = docValues.longValue();
            sumByKey.compute(number, (key, oldValue) -> {
                if (oldValue == null) {
                    return number;
                } else {
                    return oldValue + number;
                }
            });
        }
    }
    return sumByKey;
}
 
Example 7
Source File: DocValuesAggregates.java    From crate with Apache License 2.0 5 votes vote down vote up
@SuppressWarnings({"unchecked", "rawtypes"})
private static Iterable<Row> getRow(AtomicReference<Throwable> killed,
                                    Searcher searcher,
                                    Query query,
                                    List<DocValueAggregator> aggregators) throws IOException {
    IndexSearcher indexSearcher = searcher.searcher();
    Weight weight = indexSearcher.createWeight(indexSearcher.rewrite(query), ScoreMode.COMPLETE_NO_SCORES, 1f);
    List<LeafReaderContext> leaves = indexSearcher.getTopReaderContext().leaves();
    Object[] cells = new Object[aggregators.size()];
    for (int i = 0; i < aggregators.size(); i++) {
        cells[i] = aggregators.get(i).initialState();
    }
    for (var leaf : leaves) {
        Scorer scorer = weight.scorer(leaf);
        if (scorer == null) {
            continue;
        }
        for (int i = 0; i < aggregators.size(); i++) {
            aggregators.get(i).loadDocValues(leaf.reader());
        }
        DocIdSetIterator docs = scorer.iterator();
        Bits liveDocs = leaf.reader().getLiveDocs();
        for (int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; doc = docs.nextDoc()) {
            if (liveDocs != null && !liveDocs.get(doc)) {
                continue;
            }
            Throwable killCause = killed.get();
            if (killCause != null) {
                Exceptions.rethrowUnchecked(killCause);
            }
            for (int i = 0; i < aggregators.size(); i++) {
                aggregators.get(i).apply(cells[i], doc);
            }
        }
    }
    for (int i = 0; i < aggregators.size(); i++) {
        cells[i] = aggregators.get(i).partialResult(cells[i]);
    }
    return List.of(new RowN(cells));
}
 
Example 8
Source File: SoftDeletesRetentionMergePolicy.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Override
public boolean keepFullyDeletedSegment(IOSupplier<CodecReader> readerIOSupplier) throws IOException {
  CodecReader reader = readerIOSupplier.get();
  /* we only need a single hit to keep it no need for soft deletes to be checked*/
  Scorer scorer = getScorer(retentionQuerySupplier.get(), FilterCodecReader.wrapLiveDocs(reader, null, reader.maxDoc()));
  if (scorer != null) {
    DocIdSetIterator iterator = scorer.iterator();
    boolean atLeastOneHit = iterator.nextDoc() != DocIdSetIterator.NO_MORE_DOCS;
    return atLeastOneHit;
  }
  return super.keepFullyDeletedSegment(readerIOSupplier) ;
}
 
Example 9
Source File: ToChildBlockJoinQuery.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
public ToChildBlockJoinScorer(Weight weight, Scorer parentScorer, BitSet parentBits, boolean doScores) {
  super(weight);
  this.doScores = doScores;
  this.parentBits = parentBits;
  this.parentScorer = parentScorer;
  this.parentIt = parentScorer.iterator();
}
 
Example 10
Source File: DrillSidewaysScorer.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
DocsAndCost(Scorer scorer, Collector sidewaysCollector) {
  final TwoPhaseIterator twoPhase = scorer.twoPhaseIterator();
  if (twoPhase == null) {
    this.approximation = scorer.iterator();
    this.twoPhase = null;
  } else {
    this.approximation = twoPhase.approximation();
    this.twoPhase = twoPhase;
  }
  this.sidewaysCollector = sidewaysCollector;
}
 
Example 11
Source File: DrillSidewaysScorer.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
DrillSidewaysScorer(LeafReaderContext context, Scorer baseScorer, Collector drillDownCollector,
                    DocsAndCost[] dims, boolean scoreSubDocsAtOnce) {
  this.dims = dims;
  this.context = context;
  this.baseScorer = baseScorer;
  this.baseIterator = baseScorer.iterator();
  this.drillDownCollector = drillDownCollector;
  this.scoreSubDocsAtOnce = scoreSubDocsAtOnce;
}
 
Example 12
Source File: PointVectorStrategy.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
  Weight w = inner.createWeight(searcher, scoreMode, 1f);
  return new ConstantScoreWeight(this, boost) {
    @Override
    public Scorer scorer(LeafReaderContext context) throws IOException {
      Scorer in = w.scorer(context);
      if (in == null)
        return null;
      DoubleValues v = distanceSource.getValues(context, DoubleValuesSource.fromScorer(in));
      DocIdSetIterator approximation = in.iterator();
      TwoPhaseIterator twoPhase = new TwoPhaseIterator(approximation) {
        @Override
        public boolean matches() throws IOException {
          return v.advanceExact(approximation.docID()) && v.doubleValue() <= limit;
        }

        @Override
        public float matchCost() {
          return 100;   // distance calculation can be heavy!
        }
      };
      return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
    }

    @Override
    public boolean isCacheable(LeafReaderContext ctx) {
      return distanceSource.isCacheable(ctx);
    }

  };
}
 
Example 13
Source File: ParentToChildrenAggregator.java    From Elasticsearch with Apache License 2.0 5 votes vote down vote up
@Override
protected void doPostCollection() throws IOException {
    IndexReader indexReader = context().searchContext().searcher().getIndexReader();
    for (LeafReaderContext ctx : indexReader.leaves()) {
        Scorer childDocsScorer = childFilter.scorer(ctx);
        if (childDocsScorer == null) {
            continue;
        }
        DocIdSetIterator childDocsIter = childDocsScorer.iterator();

        final LeafBucketCollector sub = collectableSubAggregators.getLeafCollector(ctx);
        final SortedDocValues globalOrdinals = valuesSource.globalOrdinalsValues(parentType, ctx);

        // Set the scorer, since we now replay only the child docIds
        sub.setScorer(ConstantScorer.create(childDocsIter, null, 1f));

        final Bits liveDocs = ctx.reader().getLiveDocs();
        for (int docId = childDocsIter.nextDoc(); docId != DocIdSetIterator.NO_MORE_DOCS; docId = childDocsIter.nextDoc()) {
            if (liveDocs != null && liveDocs.get(docId) == false) {
                continue;
            }
            long globalOrdinal = globalOrdinals.getOrd(docId);
            if (globalOrdinal != -1) {
                long bucketOrd = parentOrdToBuckets.get(globalOrdinal);
                if (bucketOrd != -1) {
                    collectBucket(sub, docId, bucketOrd);
                    if (multipleBucketsPerParentOrd) {
                        long[] otherBucketOrds = parentOrdToOtherBuckets.get(globalOrdinal);
                        if (otherBucketOrds != null) {
                            for (long otherBucketOrd : otherBucketOrds) {
                                collectBucket(sub, docId, otherBucketOrd);
                            }
                        }
                    }
                }
            }
        }
    }
}
 
Example 14
Source File: DoubleRangeFacetCounts.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
private void count(DoubleValuesSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {

    DoubleRange[] ranges = (DoubleRange[]) this.ranges;

    LongRange[] longRanges = new LongRange[ranges.length];
    for(int i=0;i<ranges.length;i++) {
      DoubleRange range = ranges[i];
      longRanges[i] =  new LongRange(range.label,
                                     NumericUtils.doubleToSortableLong(range.min), true,
                                     NumericUtils.doubleToSortableLong(range.max), true);
    }

    LongRangeCounter counter = new LongRangeCounter(longRanges);

    int missingCount = 0;
    for (MatchingDocs hits : matchingDocs) {
      DoubleValues fv = valueSource.getValues(hits.context, null);
      
      totCount += hits.totalHits;
      final DocIdSetIterator fastMatchDocs;
      if (fastMatchQuery != null) {
        final IndexReaderContext topLevelContext = ReaderUtil.getTopLevelContext(hits.context);
        final IndexSearcher searcher = new IndexSearcher(topLevelContext);
        searcher.setQueryCache(null);
        final Weight fastMatchWeight = searcher.createWeight(searcher.rewrite(fastMatchQuery), ScoreMode.COMPLETE_NO_SCORES, 1);
        Scorer s = fastMatchWeight.scorer(hits.context);
        if (s == null) {
          continue;
        }
        fastMatchDocs = s.iterator();
      } else {
        fastMatchDocs = null;
      }

      DocIdSetIterator docs = hits.bits.iterator();

      for (int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; ) {
        if (fastMatchDocs != null) {
          int fastMatchDoc = fastMatchDocs.docID();
          if (fastMatchDoc < doc) {
            fastMatchDoc = fastMatchDocs.advance(doc);
          }

          if (doc != fastMatchDoc) {
            doc = docs.advance(fastMatchDoc);
            continue;
          }
        }
        // Skip missing docs:
        if (fv.advanceExact(doc)) {
          counter.add(NumericUtils.doubleToSortableLong(fv.doubleValue()));
        } else {
          missingCount++;
        }

        doc = docs.nextDoc();
      }
    }

    missingCount += counter.fillCounts(counts);
    totCount -= missingCount;
  }
 
Example 15
Source File: LongRange.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
  final Weight fastMatchWeight = fastMatchQuery == null
      ? null
      : searcher.createWeight(fastMatchQuery, ScoreMode.COMPLETE_NO_SCORES, 1f);

  return new ConstantScoreWeight(this, boost) {
    @Override
    public Scorer scorer(LeafReaderContext context) throws IOException {
      final int maxDoc = context.reader().maxDoc();

      final DocIdSetIterator approximation;
      if (fastMatchWeight == null) {
        approximation = DocIdSetIterator.all(maxDoc);
      } else {
        Scorer s = fastMatchWeight.scorer(context);
        if (s == null) {
          return null;
        }
        approximation = s.iterator();
      }

      final LongValues values = valueSource.getValues(context, null);
      final TwoPhaseIterator twoPhase = new TwoPhaseIterator(approximation) {
        @Override
        public boolean matches() throws IOException {
          return values.advanceExact(approximation.docID()) && range.accept(values.longValue());
        }

        @Override
        public float matchCost() {
          return 100; // TODO: use cost of range.accept()
        }
      };
      return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
    }

    @Override
    public boolean isCacheable(LeafReaderContext ctx) {
      return valueSource.isCacheable(ctx);
    }

  };
}
 
Example 16
Source File: LongRangeFacetCounts.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
private void count(LongValuesSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {

    LongRange[] ranges = (LongRange[]) this.ranges;

    LongRangeCounter counter = new LongRangeCounter(ranges);

    int missingCount = 0;
    for (MatchingDocs hits : matchingDocs) {
      LongValues fv = valueSource.getValues(hits.context, null);
      
      totCount += hits.totalHits;
      final DocIdSetIterator fastMatchDocs;
      if (fastMatchQuery != null) {
        final IndexReaderContext topLevelContext = ReaderUtil.getTopLevelContext(hits.context);
        final IndexSearcher searcher = new IndexSearcher(topLevelContext);
        searcher.setQueryCache(null);
        final Weight fastMatchWeight = searcher.createWeight(searcher.rewrite(fastMatchQuery), ScoreMode.COMPLETE_NO_SCORES, 1);
        Scorer s = fastMatchWeight.scorer(hits.context);
        if (s == null) {
          continue;
        }
        fastMatchDocs = s.iterator();
      } else {
        fastMatchDocs = null;
      }

      DocIdSetIterator docs = hits.bits.iterator();      
      for (int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; ) {
        if (fastMatchDocs != null) {
          int fastMatchDoc = fastMatchDocs.docID();
          if (fastMatchDoc < doc) {
            fastMatchDoc = fastMatchDocs.advance(doc);
          }

          if (doc != fastMatchDoc) {
            doc = docs.advance(fastMatchDoc);
            continue;
          }
        }
        // Skip missing docs:
        if (fv.advanceExact(doc)) {
          counter.add(fv.longValue());
        } else {
          missingCount++;
        }

        doc = docs.nextDoc();
      }
    }
    
    int x = counter.fillCounts(counts);

    missingCount += x;

    //System.out.println("totCount " + totCount + " x " + x + " missingCount " + missingCount);
    totCount -= missingCount;
  }
 
Example 17
Source File: FilterableTermsEnum.java    From Elasticsearch with Apache License 2.0 4 votes vote down vote up
public FilterableTermsEnum(IndexReader reader, String field, int docsEnumFlag, @Nullable Query filter) throws IOException {
    if ((docsEnumFlag != PostingsEnum.FREQS) && (docsEnumFlag != PostingsEnum.NONE)) {
        throw new IllegalArgumentException("invalid docsEnumFlag of " + docsEnumFlag);
    }
    this.docsEnumFlag = docsEnumFlag;
    if (filter == null) {
        // Important - need to use the doc count that includes deleted docs
        // or we have this issue: https://github.com/elasticsearch/elasticsearch/issues/7951
        numDocs = reader.maxDoc();
    }
    List<LeafReaderContext> leaves = reader.leaves();
    List<Holder> enums = new ArrayList<>(leaves.size());
    final Weight weight;
    if (filter == null) {
        weight = null;
    } else {
        final IndexSearcher searcher = new IndexSearcher(reader);
        searcher.setQueryCache(null);
        weight = searcher.createNormalizedWeight(filter, false);
    }
    for (LeafReaderContext context : leaves) {
        Terms terms = context.reader().terms(field);
        if (terms == null) {
            continue;
        }
        TermsEnum termsEnum = terms.iterator();
        if (termsEnum == null) {
            continue;
        }
        BitSet bits = null;
        if (weight != null) {
            Scorer scorer = weight.scorer(context);
            if (scorer == null) {
                // fully filtered, none matching, no need to iterate on this
                continue;
            }
            DocIdSetIterator docs = scorer.iterator();

            // we want to force apply deleted docs
            final Bits liveDocs = context.reader().getLiveDocs();
            if (liveDocs != null) {
                docs = new FilteredDocIdSetIterator(docs) {
                    @Override
                    protected boolean match(int doc) {
                        return liveDocs.get(doc);
                    }
                };
            }

            BitDocIdSet.Builder builder = new BitDocIdSet.Builder(context.reader().maxDoc());
            builder.or(docs);
            bits = builder.build().bits();

            // Count how many docs are in our filtered set
            // TODO make this lazy-loaded only for those that need it?
            numDocs += bits.cardinality();
        }
        enums.add(new Holder(termsEnum, bits));
    }
    this.enums = enums.toArray(new Holder[enums.size()]);
}
 
Example 18
Source File: GeoDistanceRangeQuery.java    From Elasticsearch with Apache License 2.0 4 votes vote down vote up
@Override
public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
    final Weight boundingBoxWeight;
    if (boundingBoxFilter != null) {
        boundingBoxWeight = searcher.createNormalizedWeight(boundingBoxFilter, false);
    } else {
        boundingBoxWeight = null;
    }
    return new ConstantScoreWeight(this) {
        @Override
        public Scorer scorer(LeafReaderContext context) throws IOException {
            final DocIdSetIterator approximation;
            if (boundingBoxWeight != null) {
                Scorer s = boundingBoxWeight.scorer(context);
                if (s == null) {
                    // if the approximation does not match anything, we're done
                    return null;
                }
                approximation = s.iterator();
            } else {
                approximation = DocIdSetIterator.all(context.reader().maxDoc());
            }
            final MultiGeoPointValues values = indexFieldData.load(context).getGeoPointValues();
            final TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approximation) {
                @Override
                public boolean matches() throws IOException {
                    final int doc = approximation.docID();
                    values.setDocument(doc);
                    final int length = values.count();
                    for (int i = 0; i < length; i++) {
                        GeoPoint point = values.valueAt(i);
                        if (distanceBoundingCheck.isWithin(point.lat(), point.lon())) {
                            double d = fixedSourceDistance.calculate(point.lat(), point.lon());
                            if (d >= inclusiveLowerPoint && d <= inclusiveUpperPoint) {
                                return true;
                            }
                        }
                    }
                    return false;
                }

                @Override
                public float matchCost() {
                    if (distanceBoundingCheck == GeoDistance.ALWAYS_INSTANCE) {
                        return 0.0f;
                    } else {
                        // TODO: is this right (up to 4 comparisons from GeoDistance.SimpleDistanceBoundingCheck)?
                        return 4.0f;
                    }
                }
            };
            return new ConstantScoreScorer(this, score(), twoPhaseIterator);
        }
    };
}
 
Example 19
Source File: IndexFieldData.java    From Elasticsearch with Apache License 2.0 4 votes vote down vote up
/**
 * Get a {@link DocIdSet} that matches the inner documents.
 */
public DocIdSetIterator innerDocs(LeafReaderContext ctx) throws IOException {
    Scorer s = innerFilter.scorer(ctx);
    return s == null ? null : s.iterator();
}
 
Example 20
Source File: FetchPhase.java    From Elasticsearch with Apache License 2.0 4 votes vote down vote up
private InternalSearchHit.InternalNestedIdentity getInternalNestedIdentity(SearchContext context, int nestedSubDocId, LeafReaderContext subReaderContext, DocumentMapper documentMapper, ObjectMapper nestedObjectMapper) throws IOException {
    int currentParent = nestedSubDocId;
    ObjectMapper nestedParentObjectMapper;
    ObjectMapper current = nestedObjectMapper;
    String originalName = nestedObjectMapper.name();
    InternalSearchHit.InternalNestedIdentity nestedIdentity = null;
    do {
        Query parentFilter;
        nestedParentObjectMapper = documentMapper.findParentObjectMapper(current);
        if (nestedParentObjectMapper != null) {
            if (nestedParentObjectMapper.nested().isNested() == false) {
                current = nestedParentObjectMapper;
                continue;
            }
            parentFilter = nestedParentObjectMapper.nestedTypeFilter();
        } else {
            parentFilter = Queries.newNonNestedFilter();
        }

        Query childFilter = nestedObjectMapper.nestedTypeFilter();
        if (childFilter == null) {
            current = nestedParentObjectMapper;
            continue;
        }
        final Weight childWeight = context.searcher().createNormalizedWeight(childFilter, false);
        Scorer childScorer = childWeight.scorer(subReaderContext);
        if (childScorer == null) {
            current = nestedParentObjectMapper;
            continue;
        }
        DocIdSetIterator childIter = childScorer.iterator();

        BitSet parentBits = context.bitsetFilterCache().getBitSetProducer(parentFilter).getBitSet(subReaderContext);

        int offset = 0;
        int nextParent = parentBits.nextSetBit(currentParent);
        for (int docId = childIter.advance(currentParent + 1); docId < nextParent && docId != DocIdSetIterator.NO_MORE_DOCS; docId = childIter.nextDoc()) {
            offset++;
        }
        currentParent = nextParent;
        current = nestedObjectMapper = nestedParentObjectMapper;
        int currentPrefix = current == null ? 0 : current.name().length() + 1;
        nestedIdentity = new InternalSearchHit.InternalNestedIdentity(originalName.substring(currentPrefix), offset, nestedIdentity);
        if (current != null) {
            originalName = current.name();
        }
    } while (current != null);
    return nestedIdentity;
}