has_child query AVG score mode does not always work correctly

fixes #2750
This commit is contained in:
Shay Banon 2013-03-08 08:50:11 -08:00
parent eb956e7c09
commit cc6c07365c
2 changed files with 27 additions and 8 deletions

View File

@ -48,6 +48,7 @@ import java.util.Set;
* all parent documents having the same uid value that is collected in the first phase are emitted as hit including * all parent documents having the same uid value that is collected in the first phase are emitted as hit including
* a score based on the aggregated child scores and score type. * a score based on the aggregated child scores and score type.
*/ */
// TODO We use a score of 0 to indicate a doc was not scored in uidToScore, this means score of 0 can be problematic, if we move to HPCC, we can use lset/...
public class ChildrenQuery extends Query implements SearchContext.Rewrite { public class ChildrenQuery extends Query implements SearchContext.Rewrite {
private final SearchContext searchContext; private final SearchContext searchContext;
@ -250,7 +251,7 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite {
HashedBytesArray uid = idTypeCache.idByDoc(currentDocId); HashedBytesArray uid = idTypeCache.idByDoc(currentDocId);
currentScore = uidToScore.get(uid); currentScore = uidToScore.get(uid);
if (Float.compare(currentScore, 0) > 0) { if (currentScore != 0) {
return currentDocId; return currentDocId;
} }
} }
@ -265,7 +266,7 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite {
HashedBytesArray uid = idTypeCache.idByDoc(currentDocId); HashedBytesArray uid = idTypeCache.idByDoc(currentDocId);
currentScore = uidToScore.get(uid); currentScore = uidToScore.get(uid);
if (Float.compare(currentScore, 0) > 0) { if (currentScore != 0) {
return currentDocId; return currentDocId;
} else { } else {
return nextDoc(); return nextDoc();
@ -293,12 +294,29 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite {
currentUid = idTypeCache.idByDoc(currentDocId); currentUid = idTypeCache.idByDoc(currentDocId);
currentScore = uidToScore.get(currentUid); currentScore = uidToScore.get(currentUid);
if (Float.compare(currentScore, 0) > 0) { if (currentScore != 0) {
currentScore /= uidToCount.get(currentUid); currentScore /= uidToCount.get(currentUid);
return currentDocId; return currentDocId;
} }
} }
} }
@Override
public int advance(int target) throws IOException {
currentDocId = parentsIterator.advance(target);
if (currentDocId == DocIdSetIterator.NO_MORE_DOCS) {
return currentDocId;
}
HashedBytesArray uid = idTypeCache.idByDoc(currentDocId);
currentScore = uidToScore.get(uid);
if (currentScore != 0) {
currentScore /= uidToCount.get(currentUid);
return currentDocId;
} else {
return nextDoc();
}
}
} }
static class ChildUidCollector extends NoopCollector { static class ChildUidCollector extends NoopCollector {
@ -327,7 +345,7 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite {
HashedBytesArray parentUid = typeCache.parentIdByDoc(doc); HashedBytesArray parentUid = typeCache.parentIdByDoc(doc);
float previousScore = uidToScore.get(parentUid); float previousScore = uidToScore.get(parentUid);
float currentScore = scorer.score(); float currentScore = scorer.score();
if (Float.compare(previousScore, 0) == 0) { if (previousScore == 0) {
uidToScore.put(parentUid, currentScore); uidToScore.put(parentUid, currentScore);
} else { } else {
switch (scoreType) { switch (scoreType) {
@ -335,7 +353,7 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite {
uidToScore.adjustValue(parentUid, currentScore); uidToScore.adjustValue(parentUid, currentScore);
break; break;
case MAX: case MAX:
if (Float.compare(previousScore, currentScore) < 0) { if (currentScore > previousScore) {
uidToScore.put(parentUid, currentScore); uidToScore.put(parentUid, currentScore);
} }
break; break;
@ -374,7 +392,7 @@ public class ChildrenQuery extends Query implements SearchContext.Rewrite {
HashedBytesArray parentUid = typeCache.parentIdByDoc(doc); HashedBytesArray parentUid = typeCache.parentIdByDoc(doc);
float previousScore = uidToScore.get(parentUid); float previousScore = uidToScore.get(parentUid);
float currentScore = scorer.score(); float currentScore = scorer.score();
if (Float.compare(previousScore, 0) == 0) { if (previousScore == 0) {
uidToScore.put(parentUid, currentScore); uidToScore.put(parentUid, currentScore);
uidToCount.put(parentUid, 1); uidToCount.put(parentUid, 1);
} else { } else {

View File

@ -43,6 +43,7 @@ import java.util.Set;
* connects the matching parent docs to the related child documents * connects the matching parent docs to the related child documents
* using the {@link IdReaderTypeCache}. * using the {@link IdReaderTypeCache}.
*/ */
// TODO We use a score of 0 to indicate a doc was not scored in uidToScore, this means score of 0 can be problematic, if we move to HPCC, we can use lset/...
public class ParentQuery extends Query implements SearchContext.Rewrite { public class ParentQuery extends Query implements SearchContext.Rewrite {
private final SearchContext searchContext; private final SearchContext searchContext;
@ -258,7 +259,7 @@ public class ParentQuery extends Query implements SearchContext.Rewrite {
continue; continue;
} }
currentScore = uidToScore.get(uid); currentScore = uidToScore.get(uid);
if (Float.compare(currentScore, 0) != 0) { if (currentScore != 0) {
return currentChildDoc; return currentChildDoc;
} }
} }
@ -275,7 +276,7 @@ public class ParentQuery extends Query implements SearchContext.Rewrite {
return nextDoc(); return nextDoc();
} }
currentScore = uidToScore.get(uid); currentScore = uidToScore.get(uid);
if (Float.compare(currentScore, 0) == 0) { if (currentScore == 0) {
return nextDoc(); return nextDoc();
} }
return currentChildDoc; return currentChildDoc;