msokolov commented on code in PR #16805:
URL: https://github.com/apache/lucene/pull/16805#discussion_r4232681726
##########
lucene/join/src/java/org/apache/lucene/search/join/GenericTermsCollector.java:
##########
@@ -149,8 +157,158 @@ public BytesRefHash getCollectedTerms() {
@Override
public float[] getScoresPerTerm() {
- throw new UnsupportedOperationException("scores are not available for
" + collector);
+ return null;
}
};
}
+
+ record TermsAndScores(BytesRefHash terms, float[] scores) {}
+
+ record Manager(String fromField, boolean multipleValuesPerDocument,
ScoreMode scoreMode)
+ implements CollectorManager<GenericTermsCollector, TermsAndScores> {
+
+ @Override
+ public GenericTermsCollector newCollector() {
+ return newGenericTermsCollector(fromField, multipleValuesPerDocument,
scoreMode);
+ }
+
+ private static GenericTermsCollector newGenericTermsCollector(
+ String fromField, boolean multipleValuesPerDocument, ScoreMode
scoreMode) {
+ final GenericTermsCollector termsWithScoreCollector;
+ if (multipleValuesPerDocument) {
+ Function<SortedSetDocValues> mvFunction =
+ DocValuesTermsCollector.sortedSetDocValues(fromField);
+ termsWithScoreCollector =
GenericTermsCollector.createCollectorMV(mvFunction, scoreMode);
+ } else {
+ Function<SortedDocValues> svFunction =
DocValuesTermsCollector.sortedDocValues(fromField);
+ termsWithScoreCollector =
GenericTermsCollector.createCollectorSV(svFunction, scoreMode);
+ }
+ return termsWithScoreCollector;
+ }
+
+ @Override
+ public TermsAndScores reduce(Collection<GenericTermsCollector> collectors)
{
+ if (collectors.isEmpty()) {
+ return new TermsAndScores(new BytesRefHash(), new float[0]);
+ }
+ GenericTermsCollector first = collectors.iterator().next();
+ if (collectors.size() == 1) {
+ return new TermsAndScores(first.getCollectedTerms(),
first.getScoresPerTerm());
+ }
+ if (first.getScoresPerTerm() == null) {
+ return reduceWithoutScores(collectors);
+ } else {
+ return reduceWithScores(collectors);
+ }
+ }
+
+ private TermsAndScores
reduceWithoutScores(Collection<GenericTermsCollector> collectors) {
+ BytesRef term = new BytesRef();
+ BytesRefHash terms = null;
+ for (GenericTermsCollector collector : collectors) {
+ if (terms == null) {
+ terms = collector.getCollectedTerms();
+ } else {
+ BytesRefHash collectorTerms = collector.getCollectedTerms();
+ for (int i = 0; i < collectorTerms.size(); i++) {
+ collectorTerms.get(i, term);
+ terms.add(term);
+ }
+ }
+ }
+ return new TermsAndScores(terms, null);
+ }
+
+ private TermsAndScores reduceWithScores(Collection<GenericTermsCollector>
collectors) {
+ BytesRef term = new BytesRef();
+ BytesRefHash terms = null;
+ List<int[]> termIdMap = new ArrayList<>();
+ for (GenericTermsCollector collector : collectors) {
+ if (terms == null) {
+ terms = collector.getCollectedTerms();
+ termIdMap.add(null); // represent the identity map as null
+ } else {
+ BytesRefHash collectorTerms = collector.getCollectedTerms();
+ int[] idMap = new int[collectorTerms.size()];
+ termIdMap.add(idMap);
+ for (int i = 0; i < collectorTerms.size(); i++) {
+ collectorTerms.get(i, term);
+ int termId = terms.add(term);
+ if (termId > 0) {
+ idMap[i] = termId;
+ } else {
+ idMap[i] = -1 - termId;
+ }
+ }
+ }
+ }
+ float[] scores = new float[terms.size()];
+ int[] counts;
+ if (scoreMode == ScoreMode.Avg) {
+ counts = new int[terms.size()];
+ } else {
+ counts = null;
+ }
+ int i = 0;
+ for (GenericTermsCollector collector : collectors) {
+ mergeScores(collector, scores, counts, termIdMap.get(i++));
+ }
+ if (scoreMode == ScoreMode.Avg) {
+ for (int j = 0; j < scores.length; j++) {
+ scores[j] /= counts[j];
+ }
+ }
+ return new TermsAndScores(terms, scores);
+ }
+
+ void mergeScores(
+ GenericTermsCollector collector, float[] allScores, int[] allCounts,
int[] idMap) {
+ float[] collectorScores = collector.getScoresPerTerm();
Review Comment:
This is not what I was assuming in the case of Avg -- it has *already* been
divided. Instead we need the raw sums
--
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.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]