diff options
4 files changed, 108 insertions, 5 deletions
diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json index ffae12867fd..db5c52267aa 100644 --- a/container-search/abi-spec.json +++ b/container-search/abi-spec.json @@ -5434,6 +5434,7 @@ "public void setListFeatures(boolean)", "public boolean getListFeatures()", "public com.yahoo.search.query.ranking.MatchPhase getMatchPhase()", + "public com.yahoo.search.query.ranking.GlobalPhase getGlobalPhase()", "public com.yahoo.search.query.ranking.Matching getMatching()", "public com.yahoo.search.query.ranking.SoftTimeout getSoftTimeout()", "public com.yahoo.search.query.Sorting getSorting()", @@ -5461,6 +5462,7 @@ "public static final java.lang.String KEEPRANKCOUNT", "public static final java.lang.String RANKSCOREDROPLIMIT", "public static final java.lang.String MATCH_PHASE", + "public static final java.lang.String GLOBAL_PHASE", "public static final java.lang.String DIVERSITY", "public static final java.lang.String SOFTTIMEOUT", "public static final java.lang.String MATCHING", @@ -6934,6 +6936,26 @@ "public static final java.lang.String STRATEGY" ] }, + "com.yahoo.search.query.ranking.GlobalPhase" : { + "superClass" : "java.lang.Object", + "interfaces" : [ + "java.lang.Cloneable" + ], + "attributes" : [ + "public" + ], + "methods" : [ + "public void <init>()", + "public static com.yahoo.search.query.profile.types.QueryProfileType getArgumentType()", + "public void setRerankCount(int)", + "public java.lang.Integer getRerankCount()", + "public int hashCode()", + "public boolean equals(java.lang.Object)", + "public com.yahoo.search.query.ranking.GlobalPhase clone()", + "public bridge synthetic java.lang.Object clone()" + ], + "fields" : [ ] + }, "com.yahoo.search.query.ranking.MatchPhase" : { "superClass" : "java.lang.Object", "interfaces" : [ diff --git a/container-search/src/main/java/com/yahoo/search/query/Ranking.java b/container-search/src/main/java/com/yahoo/search/query/Ranking.java index b07b440ac62..3c2a8a83c40 100644 --- a/container-search/src/main/java/com/yahoo/search/query/Ranking.java +++ b/container-search/src/main/java/com/yahoo/search/query/Ranking.java @@ -9,6 +9,7 @@ import com.yahoo.search.query.profile.types.FieldDescription; import com.yahoo.search.query.profile.types.QueryProfileFieldType; import com.yahoo.search.query.profile.types.QueryProfileType; import com.yahoo.search.query.ranking.Diversity; +import com.yahoo.search.query.ranking.GlobalPhase; import com.yahoo.search.query.ranking.MatchPhase; import com.yahoo.search.query.ranking.Matching; import com.yahoo.search.query.ranking.RankFeatures; @@ -44,6 +45,7 @@ public class Ranking implements Cloneable { public static final String KEEPRANKCOUNT = "keepRankCount"; public static final String RANKSCOREDROPLIMIT = "rankScoreDropLimit"; public static final String MATCH_PHASE = "matchPhase"; + public static final String GLOBAL_PHASE = "globalPhase"; public static final String DIVERSITY = "diversity"; public static final String SOFTTIMEOUT = "softtimeout"; public static final String MATCHING = "matching"; @@ -65,6 +67,7 @@ public class Ranking implements Cloneable { argumentType.addField(new FieldDescription(RERANKCOUNT, "integer")); argumentType.addField(new FieldDescription(KEEPRANKCOUNT, "integer")); argumentType.addField(new FieldDescription(RANKSCOREDROPLIMIT, "double")); + argumentType.addField(new FieldDescription(GLOBAL_PHASE, new QueryProfileFieldType(GlobalPhase.getArgumentType()))); argumentType.addField(new FieldDescription(MATCH_PHASE, new QueryProfileFieldType(MatchPhase.getArgumentType()), "matchPhase")); argumentType.addField(new FieldDescription(DIVERSITY, new QueryProfileFieldType(Diversity.getArgumentType()))); argumentType.addField(new FieldDescription(SOFTTIMEOUT, new QueryProfileFieldType(SoftTimeout.getArgumentType()))); @@ -104,6 +107,8 @@ public class Ranking implements Cloneable { private MatchPhase matchPhase = new MatchPhase(); + private GlobalPhase globalPhase = new GlobalPhase(); + private Matching matching = new Matching(); private SoftTimeout softTimeout = new SoftTimeout(); @@ -215,6 +220,9 @@ public class Ranking implements Cloneable { /** Returns the match phase rank settings of this. This is never null. */ public MatchPhase getMatchPhase() { return matchPhase; } + /** Returns the global-phase rank settings of this. This is never null. */ + public GlobalPhase getGlobalPhase() { return globalPhase; } + /** Returns the matching settings of this. This is never null. */ public Matching getMatching() { return matching; } @@ -279,6 +287,7 @@ public class Ranking implements Cloneable { clone.rankProperties = this.rankProperties.clone(); clone.rankFeatures = this.rankFeatures.cloneFor(clone); clone.matchPhase = this.matchPhase.clone(); + clone.globalPhase = this.globalPhase.clone(); clone.matching = this.matching.clone(); clone.softTimeout = this.softTimeout.clone(); return clone; @@ -305,12 +314,13 @@ public class Ranking implements Cloneable { if ( ! QueryHelper.equals(this.sorting, other.sorting)) return false; if ( ! QueryHelper.equals(this.location, other.location)) return false; if ( ! QueryHelper.equals(this.profile, other.profile)) return false; + if ( ! QueryHelper.equals(this.globalPhase, other.globalPhase)) return false; return true; } @Override public int hashCode() { - return Objects.hash(rankFeatures, rankProperties, matchPhase, softTimeout, matching, sorting, location, profile); + return Objects.hash(rankFeatures, rankProperties, matchPhase, globalPhase, softTimeout, matching, sorting, location, profile); } } 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 f476ee1afc5..505759d8967 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 @@ -62,7 +62,8 @@ public class QueryProperties extends Properties { map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.MATCHING, last.toLowerCase()), accessor); } - private static final Map<CompoundName, GetterSetter> properyAccessors = createPropertySetterMap(); + private static final Map<CompoundName, GetterSetter> propertyAccessors = createPropertySetterMap(); + private static Map<CompoundName, GetterSetter> createPropertySetterMap() { Map<CompoundName, GetterSetter> map = new HashMap<>(); map.put(CompoundName.fromComponents(Model.MODEL, Model.QUERY_STRING), GetterSetter.of(query -> query.getModel().getQueryString(), (query, value) -> query.getModel().setQueryString(asString(value, "")))); @@ -84,7 +85,6 @@ public class QueryProperties extends Properties { map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.KEEPRANKCOUNT), GetterSetter.of(query -> query.getRanking().getKeepRankCount(), (query, value) -> query.getRanking().setKeepRankCount(asInteger(value, null)))); map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.RANKSCOREDROPLIMIT), GetterSetter.of(query -> query.getRanking().getRankScoreDropLimit(), (query, value) -> query.getRanking().setRankScoreDropLimit(asDouble(value, null)))); map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.LIST_FEATURES), GetterSetter.of(query -> query.getRanking().getListFeatures(), (query, value) -> query.getRanking().setListFeatures(asBoolean(value,false)))); - addDualCasedRM(map, Matching.TERMWISELIMIT, GetterSetter.of(query -> query.getRanking().getMatching().getTermwiseLimit(), (query, value) -> query.getRanking().getMatching().setTermwiselimit(asDouble(value, 1.0)))); addDualCasedRM(map, Matching.NUMTHREADSPERSEARCH, GetterSetter.of(query -> query.getRanking().getMatching().getNumThreadsPerSearch(), (query, value) -> query.getRanking().getMatching().setNumThreadsPerSearch(asInteger(value, 1)))); addDualCasedRM(map, Matching.NUMSEARCHPARTITIIONS, GetterSetter.of(query -> query.getRanking().getMatching().getNumSearchPartitions(), (query, value) -> query.getRanking().getMatching().setNumSearchPartitions(asInteger(value, 1)))); @@ -101,6 +101,9 @@ public class QueryProperties extends Properties { map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.MATCH_PHASE, Ranking.DIVERSITY, Diversity.MINGROUPS), GetterSetter.of(query -> query.getRanking().getMatchPhase().getDiversity().getMinGroups(), (query, value) -> query.getRanking().getMatchPhase().getDiversity().setMinGroups(asLong(value, null)))); map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.MATCH_PHASE, Ranking.DIVERSITY, Diversity.CUTOFF, Diversity.FACTOR), GetterSetter.of(query -> query.getRanking().getMatchPhase().getDiversity().getCutoffFactor(), (query, value) -> query.getRanking().getMatchPhase().getDiversity().setCutoffFactor(asDouble(value, 10.0)))); map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.MATCH_PHASE, Ranking.DIVERSITY, Diversity.CUTOFF, Diversity.STRATEGY), GetterSetter.of(query -> query.getRanking().getMatchPhase().getDiversity().getCutoffStrategy(), (query, value) -> query.getRanking().getMatchPhase().getDiversity().setCutoffStrategy(asString(value, "loose")))); + map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.GLOBAL_PHASE, Ranking.RERANKCOUNT), + GetterSetter.of(query -> query.getRanking().getGlobalPhase().getRerankCount(), + (query, value) -> query.getRanking().getGlobalPhase().setRerankCount(asInteger(value, null)))); map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.SOFTTIMEOUT, SoftTimeout.ENABLE), GetterSetter.of(query -> query.getRanking().getSoftTimeout().getEnable(), (query, value) -> query.getRanking().getSoftTimeout().setEnable(asBoolean(value, true)))); map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.SOFTTIMEOUT, SoftTimeout.FACTOR), GetterSetter.of(query -> query.getRanking().getSoftTimeout().getFactor(), (query, value) -> query.getRanking().getSoftTimeout().setFactor(asDouble(value, null)))); map.put(CompoundName.fromComponents(Ranking.RANKING, Ranking.SOFTTIMEOUT, SoftTimeout.TAILCOST), GetterSetter.of(query -> query.getRanking().getSoftTimeout().getTailcost(), (query, value) -> query.getRanking().getSoftTimeout().setTailcost(asDouble(value, null)))); @@ -148,7 +151,7 @@ public class QueryProperties extends Properties { public Object get(CompoundName key, Map<String, String> context, com.yahoo.processing.request.Properties substitution) { - GetterSetter propertyAccessor = properyAccessors.get(key); + GetterSetter propertyAccessor = propertyAccessors.get(key); if (propertyAccessor != null && propertyAccessor.getter != null) return propertyAccessor.getter.get(query); if (key.first().equals(Ranking.RANKING)) { @@ -164,7 +167,7 @@ public class QueryProperties extends Properties { } private void setInternal(CompoundName key, Object value, Map<String,String> context) { - GetterSetter propertyAccessor = properyAccessors.get(key); + GetterSetter propertyAccessor = propertyAccessors.get(key); if (propertyAccessor != null && propertyAccessor.setter != null) { propertyAccessor.setter.set(query, value); return; diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/GlobalPhase.java b/container-search/src/main/java/com/yahoo/search/query/ranking/GlobalPhase.java new file mode 100644 index 00000000000..7d28ae85ad1 --- /dev/null +++ b/container-search/src/main/java/com/yahoo/search/query/ranking/GlobalPhase.java @@ -0,0 +1,68 @@ +// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.query.ranking; + +import com.yahoo.search.query.Ranking; +import com.yahoo.search.query.profile.types.FieldDescription; +import com.yahoo.search.query.profile.types.FieldType; +import com.yahoo.search.query.profile.types.QueryProfileType; + +import java.util.Objects; + +/** + * The global-phase ranking settings of this query. + * + * @author arnej + */ +public class GlobalPhase implements Cloneable { + + /** The type representing the property arguments consumed by this */ + private static final QueryProfileType argumentType; + + static { + argumentType = new QueryProfileType(Ranking.GLOBAL_PHASE); + argumentType.setStrict(true); + argumentType.setBuiltin(true); + argumentType.addField(new FieldDescription(Ranking.RERANKCOUNT, FieldType.integerType)); + argumentType.freeze(); + } + public static QueryProfileType getArgumentType() { return argumentType; } + + private Integer rerankCount = null; + + /** + * Sets the number of hits for which the global-phase function will be evaluated. + * When set, this overrides the setting in the rank profile. + */ + public void setRerankCount(int rerankCount) { this.rerankCount = rerankCount; } + + /** Returns the rerank-count that will be used, or null if not set */ + public Integer getRerankCount() { return rerankCount; } + + @Override + public int hashCode() { + return Objects.hashCode(this.rerankCount); + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (o instanceof GlobalPhase other) { + if ( ! Objects.equals(this.rerankCount, other.rerankCount)) return false; + return true; + } + return false; + } + + @Override + public GlobalPhase clone() { + try { + GlobalPhase clone = (GlobalPhase)super.clone(); + clone.rerankCount = this.rerankCount; + return clone; + } + catch (CloneNotSupportedException e) { + throw new RuntimeException("Won't happen", e); + } + } + +} |