dsmiley commented on a change in pull request #1151: SOLR-13890: Add "top-level" DVTQ implementation URL: https://github.com/apache/lucene-solr/pull/1151#discussion_r365065931
########## File path: solr/core/src/java/org/apache/solr/search/TermsQParserPlugin.java ########## @@ -142,4 +158,100 @@ public Query parse() throws SyntaxError { } }; } + + private static class TopLevelDocValuesTermsQuery extends DocValuesTermsQuery { + private final String fieldName; + private SortedSetDocValues topLevelDocValues; + private LongBitSet topLevelTermOrdinals; + private boolean matchesAtLeastOneTerm = false; + + + public TopLevelDocValuesTermsQuery(String field, BytesRef... terms) { + super(field, terms); + this.fieldName = field; + } + + public Weight createWeight(IndexSearcher searcher, final ScoreMode scoreMode, float boost) throws IOException { + if (! (searcher instanceof SolrIndexSearcher)) { + log.debug("Falling back to DocValuesTermsQuery because searcher [{}] is not the required SolrIndexSearcher", searcher); + return super.createWeight(searcher, scoreMode, boost); + } + + topLevelDocValues = DocValues.getSortedSet(((SolrIndexSearcher)searcher).getSlowAtomicReader(), fieldName); + topLevelTermOrdinals = new LongBitSet(topLevelDocValues.getValueCount()); + PrefixCodedTerms.TermIterator iterator = getTerms().iterator(); + + long lastTermOrdFound = 0; + for(BytesRef term = iterator.next(); term != null; term = iterator.next()) { + long currentTermOrd = lookupTerm(topLevelDocValues, term, lastTermOrdFound); + if (currentTermOrd >= 0L) { + matchesAtLeastOneTerm = true; + topLevelTermOrdinals.set(currentTermOrd); + lastTermOrdFound = currentTermOrd; + } + } + + return new ConstantScoreWeight(this, boost) { + public Scorer scorer(LeafReaderContext context) throws IOException { + if (! matchesAtLeastOneTerm) { + return null; + } + + SortedSetDocValues segmentDocValues = context.reader().getSortedSetDocValues(fieldName); + if (segmentDocValues == null) { + return null; + } + + final int docBase = context.docBase; + return new ConstantScoreScorer(this, this.score(), scoreMode, new TwoPhaseIterator(segmentDocValues) { + public boolean matches() throws IOException { + topLevelDocValues.advanceExact(docBase + approximation.docID()); + for(long ord = topLevelDocValues.nextOrd(); ord != -1L; ord = topLevelDocValues.nextOrd()) { + if (topLevelTermOrdinals.get(ord)) { + return true; + } + } + + return false; + } + + public float matchCost() { + return 3.0F; Review comment: Compared to other TPIs, I think 3f is too low. For example DVTQ (in the superclass) is 3f but we also must call advanceExact on the top level DV. I suggest 10f. It's a bike-shed number but I just want more than 3 and much less than 100 which is what some of the no-idea but probably expensive TPIs have. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@lucene.apache.org For additional commands, e-mail: issues-h...@lucene.apache.org