do not check global minimum score on non-competitive hits since it hurts constant score queries

This commit is contained in:
jimczi 2019-10-02 10:34:03 +02:00
parent 1770f15bb5
commit 93d135e79d
2 changed files with 42 additions and 29 deletions

View File

@ -126,7 +126,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
super.setScorer(scorer); super.setScorer(scorer);
// reset the minimum competitive score // reset the minimum competitive score
minCompetitiveScore = 0f; minCompetitiveScore = 0f;
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} }
@Override @Override
@ -145,8 +145,10 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
} else { } else {
collectedAllCompetitiveHits = true; collectedAllCompetitiveHits = true;
} }
} else { } else if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO); // we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
} }
return; return;
} }
@ -155,7 +157,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
comparator.copy(bottom.slot, doc); comparator.copy(bottom.slot, doc);
updateBottom(doc); updateBottom(doc);
comparator.setBottom(bottom.slot); comparator.setBottom(bottom.slot);
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} else { } else {
// Startup transient: queue hasn't gathered numHits yet // Startup transient: queue hasn't gathered numHits yet
final int slot = totalHits - 1; final int slot = totalHits - 1;
@ -166,7 +168,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
if (queueFull) { if (queueFull) {
comparator.setBottom(bottom.slot); comparator.setBottom(bottom.slot);
} }
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} }
} }
@ -215,7 +217,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
public void setScorer(Scorable scorer) throws IOException { public void setScorer(Scorable scorer) throws IOException {
super.setScorer(scorer); super.setScorer(scorer);
minCompetitiveScore = 0f; minCompetitiveScore = 0f;
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} }
@Override @Override
@ -239,10 +241,10 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
} else { } else {
collectedAllCompetitiveHits = true; collectedAllCompetitiveHits = true;
} }
} else { } else if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we just reached totalHitsThreshold, we can start setting the min // we can start setting the min competitive score if we just
// competitive score now // reached totalHitsThreshold
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO); updateMinCompetitiveScore(scorer);
} }
return; return;
} }
@ -251,7 +253,11 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
final int topCmp = reverseMul * comparator.compareTop(doc); final int topCmp = reverseMul * comparator.compareTop(doc);
if (topCmp > 0 || (topCmp == 0 && doc <= afterDoc)) { if (topCmp > 0 || (topCmp == 0 && doc <= afterDoc)) {
// Already collected on a previous page // Already collected on a previous page
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO); if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
return; return;
} }
@ -262,7 +268,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
updateBottom(doc); updateBottom(doc);
comparator.setBottom(bottom.slot); comparator.setBottom(bottom.slot);
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} else { } else {
collectedHits++; collectedHits++;
@ -277,7 +283,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
if (queueFull) { if (queueFull) {
comparator.setBottom(bottom.slot); comparator.setBottom(bottom.slot);
} }
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} }
} }
}; };
@ -336,10 +342,10 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
return scoreMode; return scoreMode;
} }
protected void updateMinCompetitiveScore(Scorable scorer, boolean checkQueue) throws IOException { protected void updateMinCompetitiveScore(Scorable scorer) throws IOException {
if (canSetMinScore && hitsThresholdChecker.isThresholdReached()) { if (canSetMinScore && hitsThresholdChecker.isThresholdReached()) {
boolean hasChanged = false; boolean hasChanged = false;
if (checkQueue && queueFull) { if (queueFull) {
assert bottom != null && firstComparator != null; assert bottom != null && firstComparator != null;
float localMinScore = firstComparator.value(bottom.slot); float localMinScore = firstComparator.value(bottom.slot);
if (localMinScore > minCompetitiveScore) { if (localMinScore > minCompetitiveScore) {

View File

@ -64,7 +64,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
super.setScorer(scorer); super.setScorer(scorer);
// reset the minimum competitive score // reset the minimum competitive score
minCompetitiveScore = 0f; minCompetitiveScore = 0f;
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} }
@Override @Override
@ -78,10 +78,11 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
hitsThresholdChecker.incrementHitCount(); hitsThresholdChecker.incrementHitCount();
if (score <= pqTop.score) { if (score <= pqTop.score) {
// the document is not competitive but we need to update the minimum competitive score if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// if we just reached the total hits threshold or if the global minimum score (bottomValueChecker) // we can start setting the min competitive score if we just
// has been updated // reached totalHitsThreshold
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO); updateMinCompetitiveScore(scorer);
}
// Since docs are returned in-order (i.e., increasing doc Id), a document // Since docs are returned in-order (i.e., increasing doc Id), a document
// with equal score to pqTop.score cannot compete since HitQueue favors // with equal score to pqTop.score cannot compete since HitQueue favors
// documents with lower doc Ids. Therefore reject those docs too. // documents with lower doc Ids. Therefore reject those docs too.
@ -90,7 +91,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
pqTop.doc = doc + docBase; pqTop.doc = doc + docBase;
pqTop.score = score; pqTop.score = score;
pqTop = pq.updateTop(); pqTop = pq.updateTop();
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} }
}; };
@ -140,25 +141,31 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
if (score > after.score || (score == after.score && doc <= afterDoc)) { if (score > after.score || (score == after.score && doc <= afterDoc)) {
// hit was collected on a previous page // hit was collected on a previous page
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO); if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
return; return;
} }
if (score <= pqTop.score) { if (score <= pqTop.score) {
// the document is not competitive but we need to update the minimum competitive score if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// if we just reached the total hits threshold or if the global minimum score (bottomValueChecker) // we can start setting the min competitive score if we just
// has been updated // reached totalHitsThreshold
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO); updateMinCompetitiveScore(scorer);
}
// Since docs are returned in-order (i.e., increasing doc Id), a document // Since docs are returned in-order (i.e., increasing doc Id), a document
// with equal score to pqTop.score cannot compete since HitQueue favors // with equal score to pqTop.score cannot compete since HitQueue favors
// documents with lower doc Ids. Therefore reject those docs too. // documents with lower doc Ids. Therefore reject those docs too.
return; return;
} }
collectedHits++; collectedHits++;
pqTop.doc = doc + docBase; pqTop.doc = doc + docBase;
pqTop.score = score; pqTop.score = score;
pqTop = pq.updateTop(); pqTop = pq.updateTop();
updateMinCompetitiveScore(scorer, true); updateMinCompetitiveScore(scorer);
} }
}; };
} }
@ -285,10 +292,10 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
return pqTop != null && pqTop.score != Float.NEGATIVE_INFINITY; return pqTop != null && pqTop.score != Float.NEGATIVE_INFINITY;
} }
protected void updateMinCompetitiveScore(Scorable scorer, boolean checkQueue) throws IOException { protected void updateMinCompetitiveScore(Scorable scorer) throws IOException {
if (hitsThresholdChecker.isThresholdReached()) { if (hitsThresholdChecker.isThresholdReached()) {
boolean hasChanged = false; boolean hasChanged = false;
if (checkQueue && isQueueFull()) { if (isQueueFull()) {
// since we tie-break on doc id and collect in doc id order, we can require // since we tie-break on doc id and collect in doc id order, we can require
// the next float // the next float
float localMinScore = Math.nextUp(pqTop.score); float localMinScore = Math.nextUp(pqTop.score);