/** * Get a {@link BitDocIdSet} that matches the root documents. */ public BitSet rootDocs(LeafReaderContext ctx) throws IOException { return rootFilter.getBitSet(ctx); }
@Override public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException { return query.createWeight(searcher, needsScores, boost); }
/** Return the child query. */ public Query getChildQuery() { return query.getChildQuery(); }
/** * Read from a stream. */ public NestedQueryBuilder(StreamInput in) throws IOException { super(in); path = in.readString(); scoreMode = ScoreMode.values()[in.readVInt()]; query = in.readNamedWriteable(QueryBuilder.class); innerHitBuilder = in.readOptionalWriteable(InnerHitBuilder::new); ignoreUnmapped = in.readBoolean(); }
@Override protected void doWriteTo(StreamOutput out) throws IOException { out.writeString(path); out.writeVInt(scoreMode.ordinal()); out.writeNamedWriteable(query); if (out.getVersion().before(Version.V_5_5_0)) { final boolean hasInnerHit = innerHitBuilder != null; out.writeBoolean(hasInnerHit); if (hasInnerHit) { innerHitBuilder.writeToNestedBWC(out, query, path); } } else { out.writeOptionalWriteable(innerHitBuilder); } out.writeBoolean(ignoreUnmapped); }
public ESToParentBlockJoinQuery(Query childQuery, BitSetProducer parentsFilter, ScoreMode scoreMode, String path) { this(new ToParentBlockJoinQuery(childQuery, parentsFilter, scoreMode), path); }
public static String scoreModeAsString(ScoreMode scoreMode) { if (scoreMode == ScoreMode.Total) { // Lucene uses 'total' but 'sum' is more consistent with other elasticsearch APIs return "sum"; } else { return scoreMode.name().toLowerCase(Locale.ROOT); } }
@Override public String toString(String field) { return query.toString(field); }
static GenericTermsCollector createCollectorMV(Function<SortedSetDocValues> mvFunction, ScoreMode mode) { switch (mode) { case None: return wrap(new TermsCollector.MV(mvFunction)); case Avg: return new MV.Avg(mvFunction); default: return new MV(mvFunction, mode); } }
static GenericTermsCollector createCollectorSV(Function<BinaryDocValues> svFunction, ScoreMode mode) { switch (mode) { case None: return wrap(new TermsCollector.SV(svFunction)); case Avg: return new SV.Avg(svFunction); default: return new SV(svFunction, mode); } }
/** * Chooses the right {@link TermsCollector} implementation. * * @param field The field to collect terms for * @param multipleValuesPerDocument Whether the field to collect terms for has multiple values per document. * @return a {@link TermsCollector} instance */ static TermsCollector<?> create(String field, boolean multipleValuesPerDocument) { return multipleValuesPerDocument ? new MV(sortedSetDocValues(field)) : new SV(binaryDocValues(field)); }
@Override public boolean equals(Object obj) { if (sameClassAs(obj) == false) { return false; } ESToParentBlockJoinQuery that = (ESToParentBlockJoinQuery) obj; return query.equals(that.query) && Objects.equals(path, that.path); }
@Override public Query rewrite(IndexReader reader) throws IOException { Query innerRewrite = query.rewrite(reader); if (innerRewrite != query) { // Right now ToParentBlockJoinQuery always rewrites to a ToParentBlockJoinQuery // so the else block will never be used. It is useful in the case that // ToParentBlockJoinQuery one day starts to rewrite to a different query, eg. // a MatchNoDocsQuery if it realizes that it cannot match any docs and rewrites // to a MatchNoDocsQuery. In that case it would be fine to lose information // about the nested path. if (innerRewrite instanceof ToParentBlockJoinQuery) { return new ESToParentBlockJoinQuery((ToParentBlockJoinQuery) innerRewrite, path); } else { return innerRewrite; } } return super.rewrite(reader); }
Query q = new ParentChildrenBlockJoinQuery(parentFilter, childFilter, parentDocId); Weight weight = context.searcher().createNormalizedWeight(q, false); if (size() == 0) {
if (objectMapper != null) { childQuery = Queries.filtered(childQuery, new ToChildBlockJoinQuery(parentQuery, context.bitsetFilter(objectMapper.nestedTypeFilter())));
@Override protected LeafBucketCollector getLeafCollector(LeafReaderContext ctx, final LeafBucketCollector sub) throws IOException { // In ES if parent is deleted, then also the children are deleted, so the child docs this agg receives // must belong to parent docs that is alive. For this reason acceptedDocs can be null here. final BitSet parentDocs = parentBitsetProducer.getBitSet(ctx); if (parentDocs == null) { return LeafBucketCollector.NO_OP_COLLECTOR; } final LongIntHashMap bucketOrdToLastCollectedParentDoc = new LongIntHashMap(32); return new LeafBucketCollectorBase(sub, null) { @Override public void collect(int childDoc, long bucket) throws IOException { // fast forward to retrieve the parentDoc this childDoc belongs to final int parentDoc = parentDocs.nextSetBit(childDoc); assert childDoc <= parentDoc && parentDoc != DocIdSetIterator.NO_MORE_DOCS; int keySlot = bucketOrdToLastCollectedParentDoc.indexOf(bucket); if (bucketOrdToLastCollectedParentDoc.indexExists(keySlot)) { int lastCollectedParentDoc = bucketOrdToLastCollectedParentDoc.indexGet(keySlot); if (parentDoc > lastCollectedParentDoc) { collectBucket(sub, parentDoc, bucket); bucketOrdToLastCollectedParentDoc.indexReplace(keySlot, parentDoc); } } else { collectBucket(sub, parentDoc, bucket); bucketOrdToLastCollectedParentDoc.indexInsert(keySlot, bucket, parentDoc); } } }; }
Scorer childDocsScorer = weight.scorer(ctx); final BitSet parentDocs = parentFilter.getBitSet(ctx); final DocIdSetIterator childDocs = childDocsScorer != null ? childDocsScorer.iterator() : null; if (collectsFromSingleBucket) {
private int findRootDocumentIfNested(SearchContext context, LeafReaderContext subReaderContext, int subDocId) throws IOException { if (context.mapperService().hasNested()) { BitSet bits = context.bitsetFilterCache() .getBitSetProducer(Queries.newNonNestedFilter(context.indexShard().indexSettings().getIndexVersionCreated())) .getBitSet(subReaderContext); if (!bits.get(subDocId)) { return bits.nextSetBit(subDocId); } } return -1; }
parentBitSet = null; } else { parentBitSet = nestedParentBitSetProducer.getBitSet(context); if (parentBitSet == null) { return null; // no matches
BitSet parentBits = context.bitsetFilterCache().getBitSetProducer(parentFilter).getBitSet(subReaderContext);