@Override public TwoPhaseIterator twoPhaseIterator() { final TwoPhaseIterator inTwoPhase = this.in.twoPhaseIterator(); final DocIdSetIterator approximation = inTwoPhase == null ? in.iterator() : inTwoPhase.approximation(); return new TwoPhaseIterator(approximation) { @Override public boolean matches() throws IOException { // we need to check the two-phase iterator first // otherwise calling score() is illegal if (inTwoPhase != null && inTwoPhase.matches() == false) { return false; } return in.score() >= minScore; } @Override public float matchCost() { return 1000f // random constant for the score computation + (inTwoPhase == null ? 0 : inTwoPhase.matchCost()); } }; }
private void addMatchedQueries(HitContext hitContext, ImmutableMap<String, Query> namedQueries, List<String> matchedQueries) throws IOException { for (Map.Entry<String, Query> entry : namedQueries.entrySet()) { String name = entry.getKey(); Query filter = entry.getValue(); final Weight weight = hitContext.topLevelSearcher().createNormalizedWeight(filter, false); final Scorer scorer = weight.scorer(hitContext.readerContext()); if (scorer == null) { continue; } final TwoPhaseIterator twoPhase = scorer.twoPhaseIterator(); if (twoPhase == null) { if (scorer.iterator().advance(hitContext.docId()) == hitContext.docId()) { matchedQueries.add(name); } } else { if (twoPhase.approximation().advance(hitContext.docId()) == hitContext.docId() && twoPhase.matches()) { matchedQueries.add(name); } } } }
@Override public final TwoPhaseIterator twoPhaseIterator() { return new TwoPhaseIterator(approximation.iterator()) { @Override public boolean matches() throws IOException { return matchDocId(approximation.docID()); } @Override public float matchCost() { return MATCH_COST; } }; }
@Override public TwoPhaseIterator twoPhaseIterator() { return new TwoPhaseIterator(conjunction) { @Override public boolean matches() throws IOException { return seqSpanFreq() > 0; } @Override public float matchCost() { return matchCost; } }; }
@Override public final DocIdSetIterator iterator() { return TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator()); }
@Override public DocIdSetIterator iterator() { return TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator()); }
private static Scorer scorer(int maxDoc, final int[] docs, final float[] scores, final boolean twoPhase) { final DocIdSetIterator iterator = twoPhase ? DocIdSetIterator.all(maxDoc) : iterator(docs); return new Scorer(null) { public DocIdSetIterator iterator() { if (twoPhase) { return TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator()); } else { return iterator; } } public TwoPhaseIterator twoPhaseIterator() { if (twoPhase) { return new TwoPhaseIterator(iterator) { @Override public boolean matches() throws IOException { return Arrays.binarySearch(docs, iterator.docID()) >= 0; } @Override public float matchCost() { return 10; } }; } else { return null; } } @Override public int docID() { return iterator.docID(); } @Override public float score() throws IOException { final int idx = Arrays.binarySearch(docs, docID()); return scores[idx]; } @Override public int freq() throws IOException { return 1; } }; }
@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); } }; }
@Override public TwoPhaseIterator twoPhaseIterator() { return spans.asTwoPhaseIterator(); }