下面列出了怎么用org.apache.lucene.search.TwoPhaseIterator的API类实例代码及写法,或者点击链接到github查看源代码。
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 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());
}
};
}
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
TwoPhaseIterator it = predicateValueSource.iterator(context, approximation);
return new ConstantScoreScorer(this, score(), scoreMode, it);
}
@Override
public boolean isCacheable(LeafReaderContext ctx) {
return predicateValueSource.isCacheable(ctx);
}
};
}
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
final Weight indexQueryWeight = indexQuery.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, boost);//scores aren't unsupported
return new ConstantScoreWeight(this, boost) {
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
final Scorer indexQueryScorer = indexQueryWeight.scorer(context);
if (indexQueryScorer == null) {
return null;
}
final TwoPhaseIterator predFuncValues = predicateValueSource.iterator(context, indexQueryScorer.iterator());
return new ConstantScoreScorer(this, score(), scoreMode, predFuncValues);
}
@Override
public boolean isCacheable(LeafReaderContext ctx) {
return predicateValueSource.isCacheable(ctx);
}
};
}
protected ValueSourceScorer(Weight weight, LeafReaderContext readerContext, FunctionValues values) {
super(weight);
this.values = values;
final DocIdSetIterator approximation = DocIdSetIterator.all(readerContext.reader().maxDoc()); // no approximation!
this.twoPhaseIterator = new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
return ValueSourceScorer.this.matches(approximation.docID());
}
@Override
public float matchCost() {
return ValueSourceScorer.this.matchCost();
}
};
this.disi = TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator);
}
@Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
// The default implementation would delegate to the joinQuery's Weight, which
// matches on children. We need to match on the parent instead
Scorer scorer = scorer(context);
if (scorer == null) {
return null;
}
final TwoPhaseIterator twoPhase = scorer.twoPhaseIterator();
if (twoPhase == null) {
if (scorer.iterator().advance(doc) != doc) {
return null;
}
}
else {
if (twoPhase.approximation().advance(doc) != doc || twoPhase.matches() == false) {
return null;
}
}
return MatchesUtils.MATCH_WITH_NO_TERMS;
}
@Override
protected TwoPhaseIterator createTwoPhaseIterator(DocIdSetIterator approximation) {
return new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
if (values.advanceExact(approximation.docID())) {
final long segmentOrd = values.ordValue();
final long globalOrd = segmentOrdToGlobalOrdLookup.get(segmentOrd);
if (foundOrds.get(globalOrd)) {
return true;
}
}
return false;
}
@Override
public float matchCost() {
return 100; // TODO: use cost of values.getOrd() and foundOrds.get()
}
};
}
@Override
protected TwoPhaseIterator createTwoPhaseIterator(DocIdSetIterator approximation) {
return new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
if (values.advanceExact(approximation.docID()) && foundOrds.get(values.ordValue())) {
return true;
}
return false;
}
@Override
public float matchCost() {
return 100; // TODO: use cost of values.getOrd() and foundOrds.get()
}
};
}
@Override
protected TwoPhaseIterator createTwoPhaseIterator(DocIdSetIterator approximation) {
return new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
if (values.advanceExact(approximation.docID())) {
final long segmentOrd = values.ordValue();
final int globalOrd = (int) segmentOrdToGlobalOrdLookup.get(segmentOrd);
if (collector.match(globalOrd)) {
score = collector.score(globalOrd);
return true;
}
}
return false;
}
@Override
public float matchCost() {
return 100; // TODO: use cost of values.getOrd() and collector.score()
}
};
}
@Override
protected TwoPhaseIterator createTwoPhaseIterator(DocIdSetIterator approximation) {
return new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
if (values.advanceExact(approximation.docID())) {
final int segmentOrd = values.ordValue();
if (collector.match(segmentOrd)) {
score = collector.score(segmentOrd);
return true;
}
}
return false;
}
@Override
public float matchCost() {
return 100; // TODO: use cost.getOrd() of values and collector.score()
}
};
}
@Override
public final TwoPhaseIterator asTwoPhaseIterator() {
TwoPhaseIterator inner = in.asTwoPhaseIterator();
if (inner != null) {
// wrapped instance has an approximation
return new TwoPhaseIterator(inner.approximation()) {
@Override
public boolean matches() throws IOException {
return inner.matches() && twoPhaseCurrentDocMatches();
}
@Override
public float matchCost() {
return inner.matchCost(); // underestimate
}
@Override
public String toString() {
return "[email protected](inner=" + inner + ", in=" + in + ")";
}
};
} else {
// wrapped instance has no approximation, but
// we can still defer matching until absolutely needed.
return new TwoPhaseIterator(in) {
@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);
}
};
}
public TwoPhaseIterator iterator(LeafReaderContext ctx, DocIdSetIterator approximation) throws IOException {
final ShapeValues shapeValues = shapeValuesource.getValues(ctx);
return new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
return shapeValues.advanceExact(approximation.docID()) && op.evaluate(shapeValues.value(), queryShape);
}
@Override
public float matchCost() {
return 100; // is this necessary?
}
};
}
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
DoubleValuesSource vs = source.rewrite(searcher);
return new ConstantScoreWeight(this, boost) {
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
DoubleValues values = vs.getValues(context, null);
DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
TwoPhaseIterator twoPhase = new TwoPhaseIterator(approximation) {
@Override
public boolean matches() throws IOException {
return values.advanceExact(approximation.docID()) && filter.test(values.doubleValue());
}
@Override
public float matchCost() {
return 100; // TODO maybe DoubleValuesSource should have a matchCost?
}
};
return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
}
@Override
public boolean isCacheable(LeafReaderContext ctx) {
return source.isCacheable(ctx);
}
};
}
@Override
public TwoPhaseIterator twoPhaseIterator() {
return new TwoPhaseIterator(intervals) {
@Override
public boolean matches() throws IOException {
return intervals.nextInterval() != IntervalIterator.NO_MORE_INTERVALS;
}
@Override
public float matchCost() {
return intervals.matchCost();
}
};
}
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;
}
@Override
public DocIdSetIterator iterator() {
if (parentTwoPhase == null) {
// the approximation is exact
return parentApproximation;
} else {
return TwoPhaseIterator.asDocIdSetIterator(parentTwoPhase);
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
final TwoPhaseIterator iterator = in.asTwoPhaseIterator();
if (iterator == null) {
return null;
}
return new AssertingTwoPhaseView(iterator);
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (queueSpans == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (spans1 == null || spans2 == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (spans == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
return spans.asTwoPhaseIterator();
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (spans1 == null || spans2 == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
TwoPhaseIterator twoPhaseIterator1 = spans1.spans.asTwoPhaseIterator();
if (twoPhaseIterator1 != null) {
return new TwoPhaseIterator(twoPhaseIterator1.approximation()) {
@Override
public boolean matches() throws IOException {
return twoPhaseIterator1.matches() && twoPhaseCurrentDocMatches();
}
@Override
public float matchCost() {
return twoPhaseIterator1.matchCost();
}
};
} else {
return new TwoPhaseIterator(spans1.spans) {
@Override
public boolean matches() throws IOException {
return twoPhaseCurrentDocMatches();
}
@Override
public float matchCost() {
return spans1.spans.positionsCost();
}
};
}
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (!query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (spans == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
return spans.asTwoPhaseIterator();
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (!query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (spans1 == null || spans2 == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (spans == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (!query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (spans1 == null || spans2 == null || !query.twoPhaseIteratorAllowed()) {
return null;
} else {
// TODO
return null;
}
}
@Override
public TwoPhaseIterator asTwoPhaseIterator() {
if (!query.twoPhaseIteratorAllowed()) {
return null;
} else {
TwoPhaseIterator originalTwoPhaseIterator = subSpans.asTwoPhaseIterator();
if (originalTwoPhaseIterator != null) {
return new TwoPhaseIterator(originalTwoPhaseIterator.approximation()) {
@Override
public boolean matches() throws IOException {
return originalTwoPhaseIterator.matches()
&& twoPhaseCurrentDocMatches();
}
@Override
public float matchCost() {
return originalTwoPhaseIterator.matchCost();
}
};
} else {
return new TwoPhaseIterator(subSpans) {
@Override
public boolean matches() throws IOException {
return twoPhaseCurrentDocMatches();
}
@Override
public float matchCost() {
return subSpans.positionsCost();
}
};
}
}
}