diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2022-04-29 15:26:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-29 15:26:42 +0200 |
commit | ebf3e94b26c5645b756c32c108717908a552b9a0 (patch) | |
tree | 1b89ba150b1b9330f8f929ae85323ac1ce495ffb | |
parent | b10ddfc638fe0ac04e766f13ac5e91fa3ec69de8 (diff) | |
parent | fb058fff6e52e2bedcee66fd92349a60749bde4b (diff) |
Merge pull request #22364 from vespa-engine/geirst/approximate-nearest-neighbor-threshold-settings
Support approximate nearest neighbor threshold settings
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) { |