From 61b256262308d3483d11e0f2f8a738a6e918f534 Mon Sep 17 00:00:00 2001 From: "jayson.minard" Date: Thu, 22 Dec 2011 00:19:38 -0800 Subject: [PATCH] Query DSL: custom_filters_score allow score_mode for "min" and "multiply", closes #1560 --- .../function/FiltersFunctionScoreQuery.java | 30 +++++++++++++++++-- .../query/CustomFiltersScoreQueryParser.java | 4 +++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/elasticsearch/common/lucene/search/function/FiltersFunctionScoreQuery.java b/src/main/java/org/elasticsearch/common/lucene/search/function/FiltersFunctionScoreQuery.java index a54a2711d9b..2c682f556c0 100644 --- a/src/main/java/org/elasticsearch/common/lucene/search/function/FiltersFunctionScoreQuery.java +++ b/src/main/java/org/elasticsearch/common/lucene/search/function/FiltersFunctionScoreQuery.java @@ -69,7 +69,7 @@ public class FiltersFunctionScoreQuery extends Query { } } - public static enum ScoreMode {First, Avg, Max, Total} + public static enum ScoreMode {First, Avg, Max, Total, Min, Multiply} Query subQuery; final FilterFunction[] filterFunctions; @@ -178,7 +178,9 @@ public class FiltersFunctionScoreQuery extends Query { } else { int count = 0; float total = 0; + float multiply = 1; float max = Float.NEGATIVE_INFINITY; + float min = Float.POSITIVE_INFINITY; ArrayList filtersExplanations = new ArrayList(); for (FilterFunction filterFunction : filterFunctions) { DocSet docSet = DocSets.convert(reader, filterFunction.filter.getDocIdSet(reader)); @@ -188,7 +190,9 @@ public class FiltersFunctionScoreQuery extends Query { float sc = functionExplanation.getValue(); count++; total += sc; + multiply *= sc; max = Math.max(sc, max); + min = Math.min(sc, min); Explanation res = new ComplexExplanation(true, sc, "custom score, product of:"); res.addDetail(new Explanation(1.0f, "match filter: " + filterFunction.filter.toString())); res.addDetail(functionExplanation); @@ -205,9 +209,15 @@ public class FiltersFunctionScoreQuery extends Query { case Max: sc = max; break; + case Min: + sc = min; + break; case Total: sc = total; break; + case Multiply: + sc = multiply; + break; } sc *= getValue(); Explanation res = new ComplexExplanation(true, sc, "custom score, score mode [" + scoreMode.toString().toLowerCase() + "]"); @@ -279,12 +289,25 @@ public class FiltersFunctionScoreQuery extends Query { if (maxScore != Float.NEGATIVE_INFINITY) { score = maxScore; } + } else if (scoreMode == ScoreMode.Min) { + float minScore = Float.POSITIVE_INFINITY; + for (int i = 0; i < filterFunctions.length; i++) { + if (docSets[i].get(docId)) { + minScore = Math.min(filterFunctions[i].function.score(docId, score), minScore); + } + } + if (minScore != Float.POSITIVE_INFINITY) { + score = minScore; + } } else { // Avg / Total float totalScore = 0.0f; + float multiplicativeScore = 1.0f; int count = 0; for (int i = 0; i < filterFunctions.length; i++) { if (docSets[i].get(docId)) { - totalScore += filterFunctions[i].function.score(docId, score); + float tempScore = filterFunctions[i].function.score(docId, score); + totalScore += tempScore; + multiplicativeScore *= tempScore; count++; } } @@ -293,6 +316,9 @@ public class FiltersFunctionScoreQuery extends Query { if (scoreMode == ScoreMode.Avg) { score /= count; } + else if (scoreMode == ScoreMode.Multiply) { + score = multiplicativeScore; + } } } return subQueryWeight * score; diff --git a/src/main/java/org/elasticsearch/index/query/CustomFiltersScoreQueryParser.java b/src/main/java/org/elasticsearch/index/query/CustomFiltersScoreQueryParser.java index c2a95572008..2d0d0249a35 100644 --- a/src/main/java/org/elasticsearch/index/query/CustomFiltersScoreQueryParser.java +++ b/src/main/java/org/elasticsearch/index/query/CustomFiltersScoreQueryParser.java @@ -120,8 +120,12 @@ public class CustomFiltersScoreQueryParser implements QueryParser { scoreMode = FiltersFunctionScoreQuery.ScoreMode.Avg; } else if ("max".equals(sScoreMode)) { scoreMode = FiltersFunctionScoreQuery.ScoreMode.Max; + } else if ("min".equals(sScoreMode)) { + scoreMode = FiltersFunctionScoreQuery.ScoreMode.Min; } else if ("total".equals(sScoreMode)) { scoreMode = FiltersFunctionScoreQuery.ScoreMode.Total; + } else if ("multiply".equals(sScoreMode)) { + scoreMode = FiltersFunctionScoreQuery.ScoreMode.Multiply; } else if ("first".equals(sScoreMode)) { scoreMode = FiltersFunctionScoreQuery.ScoreMode.First; } else {