aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2022-04-29 15:26:42 +0200
committerGitHub <noreply@github.com>2022-04-29 15:26:42 +0200
commitebf3e94b26c5645b756c32c108717908a552b9a0 (patch)
tree1b89ba150b1b9330f8f929ae85323ac1ce495ffb
parentb10ddfc638fe0ac04e766f13ac5e91fa3ec69de8 (diff)
parentfb058fff6e52e2bedcee66fd92349a60749bde4b (diff)
Merge pull request #22364 from vespa-engine/geirst/approximate-nearest-neighbor-threshold-settings
Support approximate nearest neighbor threshold settings
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java18
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java11
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedRanking.java4
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java17
-rw-r--r--config-model/src/main/javacc/IntermediateParser.jj30
-rw-r--r--config-model/src/main/javacc/SDParser.jj33
-rw-r--r--config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java55
-rw-r--r--container-search/abi-spec.json16
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java81
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java17
11 files changed, 236 insertions, 50 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java
index 029c0efb55f..9c802075462 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java
@@ -93,6 +93,8 @@ public class RankProfile implements Cloneable {
private int numSearchPartitions = -1;
private Double termwiseLimit = null;
+ private Double postFilterThreshold = null;
+ private Double approximateThreshold = null;
/** The drop limit used to drop hits with rank score less than or equal to this value */
private double rankScoreDropLimit = -Double.MAX_VALUE;
@@ -688,6 +690,8 @@ public class RankProfile implements Cloneable {
}
public void setTermwiseLimit(double termwiseLimit) { this.termwiseLimit = termwiseLimit; }
+ public void setPostFilterThreshold(double threshold) { this.postFilterThreshold = threshold; }
+ public void setApproximateThreshold(double threshold) { this.approximateThreshold = threshold; }
public OptionalDouble getTermwiseLimit() {
if (termwiseLimit != null) return OptionalDouble.of(termwiseLimit);
@@ -695,6 +699,20 @@ public class RankProfile implements Cloneable {
.orElse(OptionalDouble.empty());
}
+ public OptionalDouble getPostFilterThreshold() {
+ if (postFilterThreshold != null) {
+ return OptionalDouble.of(postFilterThreshold);
+ }
+ return uniquelyInherited(p -> p.getPostFilterThreshold(), l -> l.isPresent(), "post-filter-threshold").orElse(OptionalDouble.empty());
+ }
+
+ public OptionalDouble getApproximateThreshold() {
+ if (approximateThreshold != null) {
+ return OptionalDouble.of(approximateThreshold);
+ }
+ return uniquelyInherited(p -> p.getApproximateThreshold(), l -> l.isPresent(), "approximate-threshold").orElse(OptionalDouble.empty());
+ }
+
/** Whether we should ignore the default rank features. Set to null to use inherited */
public void setIgnoreDefaultRankFeatures(Boolean ignoreDefaultRankFeatures) {
this.ignoreDefaultRankFeatures = ignoreDefaultRankFeatures;
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java
index dba5397c6c3..3c14a2b9c63 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java
@@ -33,6 +33,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.OptionalDouble;
import java.util.Set;
import java.util.stream.Collectors;
@@ -134,6 +135,8 @@ public class RawRankProfile implements RankProfilesConfig.Producer {
private final int minHitsPerThread;
private final int numSearchPartitions;
private final double termwiseLimit;
+ private final OptionalDouble postFilterThreshold;
+ private final OptionalDouble approximateThreshold;
private final double rankScoreDropLimit;
private final boolean mapBackRankingExpressionFeatures;
@@ -170,6 +173,8 @@ public class RawRankProfile implements RankProfilesConfig.Producer {
minHitsPerThread = compiled.getMinHitsPerThread();
numSearchPartitions = compiled.getNumSearchPartitions();
termwiseLimit = compiled.getTermwiseLimit().orElse(deployProperties.featureFlags().defaultTermwiseLimit());
+ postFilterThreshold = compiled.getPostFilterThreshold();
+ approximateThreshold = compiled.getApproximateThreshold();
keepRankCount = compiled.getKeepRankCount();
rankScoreDropLimit = compiled.getRankScoreDropLimit();
mapBackRankingExpressionFeatures = deployProperties.featureFlags().avoidRenamingSummaryFeatures();
@@ -382,6 +387,12 @@ public class RawRankProfile implements RankProfilesConfig.Producer {
if (termwiseLimit < 1.0) {
properties.add(new Pair<>("vespa.matching.termwise_limit", termwiseLimit + ""));
}
+ if (postFilterThreshold.isPresent()) {
+ properties.add(new Pair<>("vespa.matching.global_filter.upper_limit", String.valueOf(postFilterThreshold.getAsDouble())));
+ }
+ if (approximateThreshold.isPresent()) {
+ properties.add(new Pair<>("vespa.matching.global_filter.lower_limit", String.valueOf(approximateThreshold.getAsDouble())));
+ }
if (matchPhaseSettings != null) {
properties.add(new Pair<>("vespa.matchphase.degradation.attribute", matchPhaseSettings.getAttribute()));
properties.add(new Pair<>("vespa.matchphase.degradation.ascendingorder", matchPhaseSettings.getAscending() + ""));
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedRanking.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedRanking.java
index d151776dd85..b50d5bf0cf8 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedRanking.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ConvertParsedRanking.java
@@ -70,6 +70,10 @@ public class ConvertParsedRanking {
(value -> profile.setRankScoreDropLimit(value));
parsed.getTermwiseLimit().ifPresent
(value -> profile.setTermwiseLimit(value));
+ parsed.getPostFilterThreshold().ifPresent
+ (value -> profile.setPostFilterThreshold(value));
+ parsed.getApproximateThreshold().ifPresent
+ (value -> profile.setApproximateThreshold(value));
parsed.getKeepRankCount().ifPresent
(value -> profile.setKeepRankCount(value));
parsed.getMinHitsPerThread().ifPresent
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java
index 1918f31749d..118945369d3 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java
@@ -28,6 +28,8 @@ class ParsedRankProfile extends ParsedBlock {
private boolean ignoreDefaultRankFeatures = false;
private Double rankScoreDropLimit = null;
private Double termwiseLimit = null;
+ private Double postFilterThreshold = null;
+ private Double approximateThreshold = null;
private final List<FeatureList> matchFeatures = new ArrayList<>();
private final List<FeatureList> rankFeatures = new ArrayList<>();
private final List<FeatureList> summaryFeatures = new ArrayList<>();
@@ -59,6 +61,8 @@ class ParsedRankProfile extends ParsedBlock {
boolean getIgnoreDefaultRankFeatures() { return this.ignoreDefaultRankFeatures; }
Optional<Double> getRankScoreDropLimit() { return Optional.ofNullable(this.rankScoreDropLimit); }
Optional<Double> getTermwiseLimit() { return Optional.ofNullable(this.termwiseLimit); }
+ Optional<Double> getPostFilterThreshold() { return Optional.ofNullable(this.postFilterThreshold); }
+ Optional<Double> getApproximateThreshold() { return Optional.ofNullable(this.approximateThreshold); }
List<FeatureList> getMatchFeatures() { return List.copyOf(this.matchFeatures); }
List<FeatureList> getRankFeatures() { return List.copyOf(this.rankFeatures); }
List<FeatureList> getSummaryFeatures() { return List.copyOf(this.summaryFeatures); }
@@ -202,6 +206,15 @@ class ParsedRankProfile extends ParsedBlock {
verifyThat(termwiseLimit == null, "already has termwise-limit");
this.termwiseLimit = limit;
}
-
-
+
+ void setPostFilterThreshold(double threshold) {
+ verifyThat(postFilterThreshold == null, "already has post-filter-threshold");
+ this.postFilterThreshold = threshold;
+ }
+
+ void setApproximateThreshold(double threshold) {
+ verifyThat(approximateThreshold == null, "already has approximate-threshold");
+ this.approximateThreshold = threshold;
+ }
+
}
diff --git a/config-model/src/main/javacc/IntermediateParser.jj b/config-model/src/main/javacc/IntermediateParser.jj
index 91dd5867307..d2d27a7a2d4 100644
--- a/config-model/src/main/javacc/IntermediateParser.jj
+++ b/config-model/src/main/javacc/IntermediateParser.jj
@@ -331,6 +331,8 @@ TOKEN :
| < MINHITSPERTHREAD: "min-hits-per-thread" >
| < NUMSEARCHPARTITIONS: "num-search-partitions" >
| < TERMWISELIMIT: "termwise-limit" >
+| < POSTFILTERTHRESHOLD: "post-filter-threshold" >
+| < APPROXIMATETHRESHOLD: "approximate-threshold" >
| < KEEPRANKCOUNT: "keep-rank-count" >
| < RANKSCOREDROPLIMIT: "rank-score-drop-limit" >
| < CONSTANTS: "constants" >
@@ -1834,6 +1836,8 @@ void rankProfileItem(ParsedRankProfile profile) : { }
| minHitsPerThread(profile)
| numSearchPartitions(profile)
| termwiseLimit(profile)
+ | postFilterThreshold(profile)
+ | approximateThreshold(profile)
| rankFeatures(profile)
| rankProperties(profile)
| secondPhase(profile)
@@ -2213,6 +2217,32 @@ void termwiseLimit(ParsedRankProfile profile) :
}
/**
+ * This rule consumes a post-filter-threshold statement for a rank profile.
+ *
+ * @param profile the rank profile to modify
+ */
+void postFilterThreshold(ParsedRankProfile profile) :
+{
+ double threshold;
+}
+{
+ (<POSTFILTERTHRESHOLD> <COLON> threshold = consumeFloat()) { profile.setPostFilterThreshold(threshold); }
+}
+
+/**
+ * This rule consumes an approximate-threshold statement for a rank profile.
+ *
+ * @param profile the rank profile to modify
+ */
+void approximateThreshold(ParsedRankProfile profile) :
+{
+ double threshold;
+}
+{
+ (<APPROXIMATETHRESHOLD> <COLON> threshold = consumeFloat()) { profile.setApproximateThreshold(threshold); }
+}
+
+/**
* This rule consumes a rank-properties block of a rank profile. There
* is a little trick within this rule to allow the final rank property
* to skip the terminating newline token.
diff --git a/config-model/src/main/javacc/SDParser.jj b/config-model/src/main/javacc/SDParser.jj
index 81631a70dbd..0ff9513885f 100644
--- a/config-model/src/main/javacc/SDParser.jj
+++ b/config-model/src/main/javacc/SDParser.jj
@@ -361,6 +361,8 @@ TOKEN :
| < MINHITSPERTHREAD: "min-hits-per-thread" >
| < NUMSEARCHPARTITIONS: "num-search-partitions" >
| < TERMWISELIMIT: "termwise-limit" >
+| < POSTFILTERTHRESHOLD: "post-filter-threshold" >
+| < APPROXIMATETHRESHOLD: "approximate-threshold" >
| < KEEPRANKCOUNT: "keep-rank-count" >
| < RANKSCOREDROPLIMIT: "rank-score-drop-limit" >
| < CONSTANTS: "constants" >
@@ -1974,6 +1976,8 @@ void rankProfileItem(RankProfile profile) : { }
| minHitsPerThread(profile)
| numSearchPartitions(profile)
| termwiseLimit(profile)
+ | postFilterThreshold(profile)
+ | approximateThreshold(profile)
| rankFeatures(profile)
| rankProperties(profile)
| secondPhase(profile)
@@ -2332,7 +2336,7 @@ void numSearchPartitions(RankProfile profile) :
}
/**
- * This rule consumes a num-threads-per-search statement for a rank profile.
+ * This rule consumes a termwise-limit statement for a rank profile.
*
* @param profile the rank profile to modify
*/
@@ -2343,6 +2347,33 @@ void termwiseLimit(RankProfile profile) :
{
(<TERMWISELIMIT> <COLON> num = consumeFloat()) { profile.setTermwiseLimit(num); }
}
+
+/**
+ * This rule consumes a post-filter-threshold statement for a rank profile.
+ *
+ * @param profile the rank profile to modify
+ */
+void postFilterThreshold(RankProfile profile) :
+{
+ double threshold;
+}
+{
+ (<POSTFILTERTHRESHOLD> <COLON> threshold = consumeFloat()) { profile.setPostFilterThreshold(threshold); }
+}
+
+/**
+ * This rule consumes an approximate-threshold statement for a rank profile.
+ *
+ * @param profile the rank profile to modify
+ */
+void approximateThreshold(RankProfile profile) :
+{
+ double threshold;
+}
+{
+ (<APPROXIMATETHRESHOLD> <COLON> threshold = consumeFloat()) { profile.setApproximateThreshold(threshold); }
+}
+
/**
* This rule consumes a rank-properties block of a rank profile. There is a little trick within this rule to allow the
* final rank property to skip the terminating newline token.
diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java
index 38ebb147cac..b89a2e09c76 100644
--- a/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java
+++ b/config-model/src/test/java/com/yahoo/searchdefinition/RankProfileTestCase.java
@@ -385,4 +385,59 @@ public class RankProfileTestCase extends AbstractSchemaTestCase {
return Optional.empty();
}
+ @Test
+ public void approximate_nearest_neighbor_threshold_settings_are_configurable() throws ParseException {
+ verifyApproximateNearestNeighborThresholdSettings(0.7, null);
+ verifyApproximateNearestNeighborThresholdSettings(null, 0.3);
+ verifyApproximateNearestNeighborThresholdSettings(0.7, 0.3);
+ }
+
+ private void verifyApproximateNearestNeighborThresholdSettings(Double postFilterThreshold, Double approximateThreshold) throws ParseException {
+ verifyApproximateNearestNeighborThresholdSettings(postFilterThreshold, approximateThreshold, false);
+ verifyApproximateNearestNeighborThresholdSettings(postFilterThreshold, approximateThreshold, true);
+ }
+
+ private void verifyApproximateNearestNeighborThresholdSettings(Double postFilterThreshold, Double approximateThreshold,
+ boolean experimentalSdParsing) throws ParseException {
+ var rankProfileRegistry = new RankProfileRegistry();
+ var props = new TestProperties();
+ props.setExperimentalSdParsing(experimentalSdParsing);
+ var queryProfileRegistry = new QueryProfileRegistry();
+ var builder = new ApplicationBuilder(rankProfileRegistry, queryProfileRegistry, props);
+ builder.addSchema(createSDWithRankProfileThresholds(postFilterThreshold, approximateThreshold));
+ builder.build(true);
+
+ var schema = builder.getSchema();
+ var rankProfile = rankProfileRegistry.get(schema, "my_profile");
+ var rawRankProfile = new RawRankProfile(rankProfile, new LargeRankExpressions(new MockFileRegistry()), queryProfileRegistry,
+ new ImportedMlModels(), new AttributeFields(schema), props);
+
+ if (postFilterThreshold != null) {
+ assertEquals((double)postFilterThreshold, rankProfile.getPostFilterThreshold().getAsDouble(), 0.000001);
+ assertEquals(String.valueOf(postFilterThreshold), findProperty(rawRankProfile.configProperties(), "vespa.matching.global_filter.upper_limit").get());
+ } else {
+ assertTrue(rankProfile.getPostFilterThreshold().isEmpty());
+ assertFalse(findProperty(rawRankProfile.configProperties(), "vespa.matching.global_filter.upper_limit").isPresent());
+ }
+
+ if (approximateThreshold != null) {
+ assertEquals((double)approximateThreshold, rankProfile.getApproximateThreshold().getAsDouble(), 0.000001);
+ assertEquals(String.valueOf(approximateThreshold), findProperty(rawRankProfile.configProperties(), "vespa.matching.global_filter.lower_limit").get());
+ } else {
+ assertTrue(rankProfile.getApproximateThreshold().isEmpty());
+ assertFalse(findProperty(rawRankProfile.configProperties(), "vespa.matching.global_filter.lower_limit").isPresent());
+ }
+ }
+
+ private String createSDWithRankProfileThresholds(Double postFilterThreshold, Double approximateThreshold) {
+ return joinLines(
+ "search test {",
+ " document test {}",
+ " rank-profile my_profile {",
+ (postFilterThreshold != null ? (" post-filter-threshold: " + postFilterThreshold) : ""),
+ (approximateThreshold != null ? (" approximate-threshold: " + approximateThreshold) : ""),
+ " }",
+ "}");
+ }
+
}
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json
index b4c4537a708..54a3b3a0f36 100644
--- a/container-search/abi-spec.json
+++ b/container-search/abi-spec.json
@@ -6851,18 +6851,22 @@
"methods": [
"public void <init>()",
"public static com.yahoo.search.query.profile.types.QueryProfileType getArgumentType()",
+ "public java.lang.Double getTermwiseLimit()",
+ "public java.lang.Integer getNumThreadsPerSearch()",
"public java.lang.Integer getNumSearchPartitions()",
- "public void setNumSearchPartitions(int)",
"public java.lang.Integer getMinHitsPerThread()",
- "public void setMinHitsPerThread(int)",
+ "public java.lang.Double getPostFilterThreshold()",
+ "public java.lang.Double getApproximateThreshold()",
"public void setTermwiselimit(double)",
- "public java.lang.Double getTermwiseLimit()",
"public void setNumThreadsPerSearch(int)",
- "public java.lang.Integer getNumThreadsPerSearch()",
+ "public void setNumSearchPartitions(int)",
+ "public void setMinHitsPerThread(int)",
+ "public void setPostFilterThreshold(double)",
+ "public void setApproximateThreshold(double)",
"public void prepare(com.yahoo.search.query.ranking.RankProperties)",
"public com.yahoo.search.query.ranking.Matching clone()",
- "public int hashCode()",
"public boolean equals(java.lang.Object)",
+ "public int hashCode()",
"public bridge synthetic java.lang.Object clone()"
],
"fields": [
@@ -6870,6 +6874,8 @@
"public static final java.lang.String NUMTHREADSPERSEARCH",
"public static final java.lang.String NUMSEARCHPARTITIIONS",
"public static final java.lang.String MINHITSPERTHREAD",
+ "public static final java.lang.String POST_FILTER_THRESHOLD",
+ "public static final java.lang.String APPROXIMATE_THRESHOLD",
"public java.lang.Double termwiseLimit"
]
},
diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
index cf9209dcc0d..0fd11d9edd7 100644
--- a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
+++ b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
@@ -263,6 +263,10 @@ public class QueryProperties extends Properties {
matching.setNumSearchPartitions(asInteger(value, 1));
else if (key.last().equals(Matching.MINHITSPERTHREAD))
matching.setMinHitsPerThread(asInteger(value, 0));
+ else if (key.last().equals(Matching.POST_FILTER_THRESHOLD))
+ matching.setPostFilterThreshold(asDouble(value, 1.0));
+ else if (key.last().equals(Matching.APPROXIMATE_THRESHOLD))
+ matching.setApproximateThreshold(asDouble(value, 0.05));
else
throwIllegalParameter(key.rest().toString(), Ranking.MATCHING);
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
index 38dcdfae9fb..65b4b62f132 100644
--- a/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
+++ b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
@@ -22,7 +22,8 @@ public class Matching implements Cloneable {
public static final String NUMTHREADSPERSEARCH = "numthreadspersearch";
public static final String NUMSEARCHPARTITIIONS = "numsearchpartitions";
public static final String MINHITSPERTHREAD = "minhitsperthread";
-
+ public static final String POST_FILTER_THRESHOLD = "postFilterThreshold";
+ public static final String APPROXIMATE_THRESHOLD = "approximateThreshold";
static {
argumentType =new QueryProfileType(Ranking.MATCHING);
@@ -32,6 +33,8 @@ public class Matching implements Cloneable {
argumentType.addField(new FieldDescription(NUMTHREADSPERSEARCH, "integer"));
argumentType.addField(new FieldDescription(NUMSEARCHPARTITIIONS, "integer"));
argumentType.addField(new FieldDescription(MINHITSPERTHREAD, "integer"));
+ argumentType.addField(new FieldDescription(POST_FILTER_THRESHOLD, "double"));
+ argumentType.addField(new FieldDescription(APPROXIMATE_THRESHOLD, "double"));
argumentType.freeze();
}
@@ -41,22 +44,15 @@ public class Matching implements Cloneable {
private Integer numThreadsPerSearch = null;
private Integer numSearchPartitions = null;
private Integer minHitsPerThread = null;
+ private Double postFilterThreshold = null;
+ private Double approximateThreshold = null;
- public Integer getNumSearchPartitions() {
- return numSearchPartitions;
- }
-
- public void setNumSearchPartitions(int numSearchPartitions) {
- this.numSearchPartitions = numSearchPartitions;
- }
-
- public Integer getMinHitsPerThread() {
- return minHitsPerThread;
- }
-
- public void setMinHitsPerThread(int minHitsPerThread) {
- this.minHitsPerThread = minHitsPerThread;
- }
+ public Double getTermwiseLimit() { return termwiseLimit; }
+ public Integer getNumThreadsPerSearch() { return numThreadsPerSearch; }
+ public Integer getNumSearchPartitions() { return numSearchPartitions; }
+ public Integer getMinHitsPerThread() { return minHitsPerThread; }
+ public Double getPostFilterThreshold() { return postFilterThreshold; }
+ public Double getApproximateThreshold() { return approximateThreshold; }
public void setTermwiselimit(double value) {
if ((value < 0.0) || (value > 1.0)) {
@@ -64,14 +60,21 @@ public class Matching implements Cloneable {
}
termwiseLimit = value;
}
-
- public Double getTermwiseLimit() { return termwiseLimit; }
-
public void setNumThreadsPerSearch(int value) {
numThreadsPerSearch = value;
}
- public Integer getNumThreadsPerSearch() { return numThreadsPerSearch; }
-
+ public void setNumSearchPartitions(int value) {
+ numSearchPartitions = value;
+ }
+ public void setMinHitsPerThread(int value) {
+ minHitsPerThread = value;
+ }
+ public void setPostFilterThreshold(double threshold) {
+ postFilterThreshold = threshold;
+ }
+ public void setApproximateThreshold(double threshold) {
+ approximateThreshold = threshold;
+ }
/** Internal operation - DO NOT USE */
public void prepare(RankProperties rankProperties) {
@@ -88,6 +91,12 @@ public class Matching implements Cloneable {
if (minHitsPerThread != null) {
rankProperties.put("vespa.matching.minhitsperthread", String.valueOf(minHitsPerThread));
}
+ if (postFilterThreshold != null) {
+ rankProperties.put("vespa.matching.global_filter.upper_limit", String.valueOf(postFilterThreshold));
+ }
+ if (approximateThreshold != null) {
+ rankProperties.put("vespa.matching.global_filter.lower_limit", String.valueOf(approximateThreshold));
+ }
}
@Override
@@ -101,27 +110,21 @@ public class Matching implements Cloneable {
}
@Override
- public int hashCode() {
- int hash = 0;
- if (termwiseLimit != null) hash += 11 * termwiseLimit.hashCode();
- if (numThreadsPerSearch != null) hash += 13 * numThreadsPerSearch.hashCode();
- if (numSearchPartitions != null) hash += 17 * numSearchPartitions.hashCode();
- if (minHitsPerThread != null) hash += 19 * minHitsPerThread.hashCode();
- return hash;
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Matching matching = (Matching) o;
+ return Objects.equals(termwiseLimit, matching.termwiseLimit) &&
+ Objects.equals(numThreadsPerSearch, matching.numThreadsPerSearch) &&
+ Objects.equals(numSearchPartitions, matching.numSearchPartitions) &&
+ Objects.equals(minHitsPerThread, matching.minHitsPerThread) &&
+ Objects.equals(postFilterThreshold, matching.postFilterThreshold) &&
+ Objects.equals(approximateThreshold, matching.approximateThreshold);
}
@Override
- public boolean equals(Object o) {
- if (o == this) return true;
- if ( ! (o instanceof Matching)) return false;
-
- Matching other = (Matching) o;
- if ( ! Objects.equals(this.termwiseLimit, other.termwiseLimit)) return false;
- if ( ! Objects.equals(this.numThreadsPerSearch, other.numThreadsPerSearch)) return false;
- if ( ! Objects.equals(this.numSearchPartitions, other.numSearchPartitions)) return false;
- if ( ! Objects.equals(this.minHitsPerThread, other.minHitsPerThread)) return false;
- return true;
+ public int hashCode() {
+ return Objects.hash(termwiseLimit, numThreadsPerSearch, numSearchPartitions, minHitsPerThread, postFilterThreshold, approximateThreshold);
}
-
}
diff --git a/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java b/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
index d4de8dba9dd..d117f88aa6a 100644
--- a/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
@@ -19,22 +19,33 @@ public class MatchingTestCase {
assertNull(query.getRanking().getMatching().getNumThreadsPerSearch());
assertNull(query.getRanking().getMatching().getNumSearchPartitions());
assertNull(query.getRanking().getMatching().getMinHitsPerThread());
-
+ assertNull(query.getRanking().getMatching().getPostFilterThreshold());
+ assertNull(query.getRanking().getMatching().getApproximateThreshold());
}
@Test
- public void testQueryOverride() {
- Query query = new Query("?query=test&ranking.matching.termwiselimit=0.7&ranking.matching.numthreadspersearch=17&ranking.matching.numsearchpartitions=13&ranking.matching.minhitsperthread=3");
+ public void testQueryOverrides() {
+ Query query = new Query("?query=test" +
+ "&ranking.matching.termwiselimit=0.7" +
+ "&ranking.matching.numthreadspersearch=17" +
+ "&ranking.matching.numsearchpartitions=13" +
+ "&ranking.matching.minhitsperthread=3" +
+ "&ranking.matching.postFilterThreshold=0.8" +
+ "&ranking.matching.approximateThreshold=0.3");
assertEquals(Double.valueOf(0.7), query.getRanking().getMatching().getTermwiseLimit());
assertEquals(Integer.valueOf(17), query.getRanking().getMatching().getNumThreadsPerSearch());
assertEquals(Integer.valueOf(13), query.getRanking().getMatching().getNumSearchPartitions());
assertEquals(Integer.valueOf(3), query.getRanking().getMatching().getMinHitsPerThread());
+ assertEquals(Double.valueOf(0.8), query.getRanking().getMatching().getPostFilterThreshold());
+ assertEquals(Double.valueOf(0.3), query.getRanking().getMatching().getApproximateThreshold());
query.prepare();
assertEquals("0.7", query.getRanking().getProperties().get("vespa.matching.termwise_limit").get(0));
assertEquals("17", query.getRanking().getProperties().get("vespa.matching.numthreadspersearch").get(0));
assertEquals("13", query.getRanking().getProperties().get("vespa.matching.numsearchpartitions").get(0));
assertEquals("3", query.getRanking().getProperties().get("vespa.matching.minhitsperthread").get(0));
+ assertEquals("0.8", query.getRanking().getProperties().get("vespa.matching.global_filter.upper_limit").get(0));
+ assertEquals("0.3", query.getRanking().getProperties().get("vespa.matching.global_filter.lower_limit").get(0));
}
private void verifyException(String key, String value) {