diff options
author | Jon Bratseth <bratseth@gmail.com> | 2022-04-07 09:41:06 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2022-04-07 09:41:06 +0200 |
commit | 48c4eba6dbc2459aae6ca4a88a4bf691669fcc5f (patch) | |
tree | 7d58659916d87795fe5f3c69e6d096535ae5f1b6 /container-search/src/main/java/com/yahoo | |
parent | 52286f5e1486eb20c2f49d37ceffb46b6121b045 (diff) |
Add RankProfileInputProperties
Diffstat (limited to 'container-search/src/main/java/com/yahoo')
8 files changed, 64 insertions, 34 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java index c45c2b1855b..d5a3e8c2786 100644 --- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java +++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/DocumentDatabase.java @@ -1,13 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.prelude.fastsearch; -import com.google.common.collect.ImmutableMap; import com.yahoo.tensor.TensorType; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -27,7 +24,7 @@ public class DocumentDatabase { private final String name; private final DocsumDefinitionSet docsumDefSet; - private final ImmutableMap<String, RankProfile> rankProfiles; + private final Map<String, RankProfile> rankProfiles; public DocumentDatabase(DocumentdbInfoConfig.Documentdb documentDb) { this(documentDb.name(), new DocsumDefinitionSet(documentDb), toRankProfiles(documentDb.rankprofile())); @@ -36,7 +33,7 @@ public class DocumentDatabase { public DocumentDatabase(String name, DocsumDefinitionSet docsumDefinitionSet, Collection<RankProfile> rankProfiles) { this.name = name; this.docsumDefSet = docsumDefinitionSet; - this.rankProfiles = ImmutableMap.copyOf(rankProfiles.stream().collect(Collectors.toMap(RankProfile::getName, p -> p))); + this.rankProfiles = Map.copyOf(rankProfiles.stream().collect(Collectors.toMap(RankProfile::getName, p -> p))); } public String getName() { @@ -50,10 +47,6 @@ public class DocumentDatabase { /** Returns an unmodifiable map of all the rank profiles in this indexed by rank profile name */ public Map<String, RankProfile> rankProfiles() { return rankProfiles; } - private static ImmutableMap<String, RankProfile> toMap(Collection<RankProfile> rankProfiles) { - return ImmutableMap.copyOf(rankProfiles.stream().collect(Collectors.toMap(RankProfile::getName, p -> p))); - } - private static Collection<RankProfile> toRankProfiles(Collection<DocumentdbInfoConfig.Documentdb.Rankprofile> rankProfileConfigList) { List<RankProfile> rankProfiles = new ArrayList<>(); for (DocumentdbInfoConfig.Documentdb.Rankprofile c : rankProfileConfigList) diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/RankProfile.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/RankProfile.java index ecc1c6bbbd5..a4248245f2a 100644 --- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/RankProfile.java +++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/RankProfile.java @@ -3,7 +3,6 @@ package com.yahoo.prelude.fastsearch; import com.yahoo.tensor.TensorType; -import java.util.Collections; import java.util.Map; /** @@ -25,7 +24,7 @@ class RankProfile { this.name = name; this.hasSummaryFeatures = hasSummaryFeatures; this.hasRankFeatures = hasRankFeatures; - this.inputs = Collections.unmodifiableMap(inputs); + this.inputs = Map.copyOf(inputs); } public String getName() { return name; } diff --git a/container-search/src/main/java/com/yahoo/search/Query.java b/container-search/src/main/java/com/yahoo/search/Query.java index 7df243404a5..7d78012bcfd 100644 --- a/container-search/src/main/java/com/yahoo/search/Query.java +++ b/container-search/src/main/java/com/yahoo/search/Query.java @@ -43,6 +43,7 @@ import com.yahoo.search.query.properties.DefaultProperties; import com.yahoo.search.query.properties.PropertyMap; import com.yahoo.search.query.properties.QueryProperties; import com.yahoo.search.query.properties.QueryPropertyAliases; +import com.yahoo.search.query.properties.RankProfileInputProperties; import com.yahoo.search.query.properties.RequestContextProperties; import com.yahoo.search.yql.NullItemException; import com.yahoo.search.yql.VespaSerializer; @@ -234,7 +235,7 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { /** The aliases of query properties */ private static final Map<String, CompoundName> propertyAliases; static { - Map<String,CompoundName> propertyAliasesBuilder = new HashMap<>(); + Map<String, CompoundName> propertyAliasesBuilder = new HashMap<>(); addAliases(Query.getArgumentType(), CompoundName.empty, propertyAliasesBuilder); propertyAliases = ImmutableMap.copyOf(propertyAliasesBuilder); } @@ -373,11 +374,12 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { setPropertiesFromRequestMap(requestMap, properties(), true); // Create the full chain - properties().chain(new QueryProperties(this, queryProfile.getRegistry(), embedders)). - chain(new ModelObjectMap()). - chain(new RequestContextProperties(requestMap, zoneInfo)). - chain(queryProfileProperties). - chain(new DefaultProperties()); + properties().chain(new RankProfileInputProperties(this)) + .chain(new QueryProperties(this, queryProfile.getRegistry(), embedders)) + .chain(new ModelObjectMap()) + .chain(new RequestContextProperties(requestMap, zoneInfo)) + .chain(queryProfileProperties) + .chain(new DefaultProperties()); // Pass the values from the query profile which maps through a field in the Query object model // through the property chain to cause those values to be set in the Query object model @@ -392,6 +394,7 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { } else { // bypass these complications if there is no query profile to get values from and validate against properties(). + chain(new RankProfileInputProperties(this)). chain(new QueryProperties(this, CompiledQueryProfileRegistry.empty, embedders)). chain(new PropertyMap()). chain(new DefaultProperties()); @@ -458,6 +461,11 @@ public class Query extends com.yahoo.processing.Request implements Cloneable { /** Calls properties.set on all entries in requestMap */ private void setPropertiesFromRequestMap(Map<String, String> requestMap, Properties properties, boolean ignoreSelect) { + // Set rank profile first because it contains type information in inputs which impacts other values set + String rankProfile = Ranking.lookupRankProfileIn(requestMap); + if (rankProfile != null) + properties.set(Ranking.RANKING + "." + Ranking.PROFILE, rankProfile, requestMap); + for (var entry : requestMap.entrySet()) { if (ignoreSelect && entry.getKey().equals(Select.SELECT)) continue; properties.set(entry.getKey(), entry.getValue(), requestMap); 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 19c1034667a..9f5b9a77547 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 @@ -16,7 +16,10 @@ import com.yahoo.search.query.ranking.RankProperties; import com.yahoo.search.query.ranking.SoftTimeout; import com.yahoo.search.result.ErrorMessage; +import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; /** * The ranking (hit ordering) settings of a query @@ -49,12 +52,17 @@ public class Ranking implements Cloneable { public static final String FEATURES = "features"; public static final String PROPERTIES = "properties"; + /** For internal use only. */ + public static String lookupRankProfileIn(Map<String, String> properties) { + return Optional.ofNullable(properties.get(RANKING + "." + PROFILE)).orElse(properties.get("ranking")); + } + static { argumentType = new QueryProfileType(RANKING); argumentType.setStrict(true); argumentType.setBuiltin(true); argumentType.addField(new FieldDescription(LOCATION, "string", "location")); - argumentType.addField(new FieldDescription(PROFILE, "string", "ranking")); + argumentType.addField(new FieldDescription(PROFILE, "string", "ranking")); // Alias repeated in lookupRankProfileIn argumentType.addField(new FieldDescription(SORTING, "string", "sorting sortspec")); argumentType.addField(new FieldDescription(LIST_FEATURES, "string", RANKFEATURES.toString())); argumentType.addField(new FieldDescription(FRESHNESS, "string", "datetime")); 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 d49a6b13b54..cf9209dcc0d 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 @@ -36,6 +36,7 @@ public class QueryProperties extends Properties { private final CompiledQueryProfileRegistry profileRegistry; private final Map<String, Embedder> embedders; + @Deprecated // TODO: Remove on Vespa 8 public QueryProperties(Query query, CompiledQueryProfileRegistry profileRegistry, Embedder embedder) { this(query, profileRegistry, Map.of(Embedder.defaultEmbedderId, embedder)); } @@ -322,20 +323,6 @@ public class QueryProperties extends Properties { throwIllegalParameter(key.last(), Select.SELECT); } } - else if (key.first().equals("rankfeature") || key.first().equals("featureoverride") ) { // featureoverride is deprecated - chained().requireSettable(key, value, context); - setRankFeature(query, key.rest().toString(), toSpecifiedType(key.rest().toString(), - value, - profileRegistry.getTypeRegistry().getComponent("features"), - context)); - } - else if (key.first().equals("rankproperty")) { - chained().requireSettable(key, value, context); - query.getRanking().getProperties().put(key.rest().toString(), toSpecifiedType(key.rest().toString(), - value, - profileRegistry.getTypeRegistry().getComponent("properties"), - context)); - } else if (key.size() == 1) { if (key.equals(Query.HITS)) query.setHits(asInteger(value,10)); diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/QueryPropertyAliases.java b/container-search/src/main/java/com/yahoo/search/query/properties/QueryPropertyAliases.java index 14f06bce6e6..e46668ffb83 100644 --- a/container-search/src/main/java/com/yahoo/search/query/properties/QueryPropertyAliases.java +++ b/container-search/src/main/java/com/yahoo/search/query/properties/QueryPropertyAliases.java @@ -23,7 +23,8 @@ public class QueryPropertyAliases extends PropertyAliases { @Override protected CompoundName unalias(CompoundName nameOrAlias) { - if (nameOrAlias.first().equalsIgnoreCase("rankfeature")) + if (nameOrAlias.first().equalsIgnoreCase("rankfeature") + || nameOrAlias.first().equalsIgnoreCase("featureoverride")) // deprecated: TODO Remove on Vespa 8 return nameOrAlias.rest().prepend("ranking", "features"); else if (nameOrAlias.first().equalsIgnoreCase("rankproperty")) return nameOrAlias.rest().prepend("ranking", "properties"); diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java b/container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java new file mode 100644 index 00000000000..6769f05bb3e --- /dev/null +++ b/container-search/src/main/java/com/yahoo/search/query/properties/RankProfileInputProperties.java @@ -0,0 +1,34 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.query.properties; + +import com.yahoo.api.annotations.Beta; +import com.yahoo.processing.request.CompoundName; +import com.yahoo.search.Query; +import com.yahoo.search.query.Properties; + +import java.util.Map; + +/** + * Verifies and converts properties according to any input declarations in the rank profile set on the query. + * + * @author bratseth + */ +@Beta +public class RankProfileInputProperties extends Properties { + + private final Query query; + + public RankProfileInputProperties(Query query) { + this.query = query; + } + + /** + * Throws IllegalInputException if the given key cannot be set to the given value. + * This default implementation just passes to the chained properties, if any. + */ + public void requireSettable(CompoundName name, Object value, Map<String, String> context) { + if (chained() != null) + chained().requireSettable(name, value, context); + } + +} diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java b/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java index db23b42afd6..ff2e3949ec4 100644 --- a/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java +++ b/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java @@ -27,7 +27,7 @@ public class RankFeatures implements Cloneable { private final Ranking parent; private final Map<String, Object> features; - /** @deprecated pass a query */ + /** @deprecated pass the parent */ @Deprecated // TODO: Remove on Vespa 8 public RankFeatures() { this(new Ranking(new Query())); |