diff options
author | Jon Bratseth <bratseth@gmail.com> | 2022-05-09 12:37:14 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2022-05-09 12:37:14 +0200 |
commit | 8ac835c8d45b538c36be97ca3de545aa73c9d29d (patch) | |
tree | c0b511602ba1de4dda2f28307860226ab9093b23 /config-model/src/main/java/com/yahoo/searchdefinition | |
parent | 032aaa3611dd82bd9eaf2366c54babb47f81a9aa (diff) |
Output input default values in rank properties
Diffstat (limited to 'config-model/src/main/java/com/yahoo/searchdefinition')
5 files changed, 79 insertions, 30 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 9c802075462..e1fe795d2b1 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java @@ -24,9 +24,9 @@ import com.yahoo.searchlib.rankingexpression.evaluation.TensorValue; import com.yahoo.searchlib.rankingexpression.evaluation.Value; import com.yahoo.searchlib.rankingexpression.rule.Arguments; import com.yahoo.searchlib.rankingexpression.rule.ReferenceNode; +import com.yahoo.tensor.Tensor; import com.yahoo.tensor.TensorType; -import java.io.File; import java.io.IOException; import java.io.Reader; import java.io.Serializable; @@ -116,7 +116,7 @@ public class RankProfile implements Cloneable { // This cache must be invalidated every time modifications are done to 'functions'. private CachedFunctions allFunctionsCached = null; - private Map<Reference, TensorType> inputs = new LinkedHashMap<>(); + private Map<Reference, Input> inputs = new LinkedHashMap<>(); private Set<String> filterFields = new HashSet<>(); @@ -764,33 +764,31 @@ public class RankProfile implements Cloneable { * All inputs must either be declared through this or in query profile types, * otherwise they are assumes to be scalars. */ - public void addInput(Reference reference, TensorType declaredType) { + public void addInput(Reference reference, Input input) { if (inputs.containsKey(reference)) { - TensorType hadType = inputs().get(reference); - if (! declaredType.equals(hadType)) - throw new IllegalArgumentException("Duplicate input '" + name + "' declared with both type " + - hadType + " and " + declaredType); + Input existing = inputs().get(reference); + if (! input.equals(existing)) + throw new IllegalArgumentException("Duplicate input: Has both " + input + " and existing"); } - inputs.put(reference, declaredType); + inputs.put(reference, input); } /** Returns the inputs of this, which also includes all inputs of the parents of this. */ // This is less restrictive than most other constructs in allowing inputs to be defined in all parent profiles // because inputs are tied closer to functions than the profile itself. - public Map<Reference, TensorType> inputs() { + public Map<Reference, Input> inputs() { if (inputs.isEmpty() && inherited().isEmpty()) return Map.of(); if (inherited().isEmpty()) return Collections.unmodifiableMap(inputs); // Combine - Map<Reference, TensorType> allInputs = new LinkedHashMap<>(); + Map<Reference, Input> allInputs = new LinkedHashMap<>(); for (var inheritedProfile : inherited()) { for (var input : inheritedProfile.inputs().entrySet()) { - TensorType existingType = allInputs.get(input.getKey()); - if (existingType != null && ! existingType.equals(input.getValue())) + Input existing = allInputs.get(input.getKey()); + if (existing != null && ! existing.equals(input.getValue())) throw new IllegalArgumentException(this + " inherits " + inheritedProfile + " which contains " + - input.getValue() + ", with type " + input.getValue() + "" + - " but this input is already defined with type " + existingType + - " in another profile this inherits"); + input.getValue() + ", but this input is already defined as " + + existing + " in another profile this inherits"); allInputs.put(input.getKey(), input.getValue()); } } @@ -1050,7 +1048,8 @@ public class RankProfile implements Cloneable { public MapEvaluationTypeContext typeContext() { return typeContext(new QueryProfileRegistry()); } private Map<Reference, TensorType> featureTypes() { - Map<Reference, TensorType> featureTypes = new HashMap<>(inputs()); + Map<Reference, TensorType> featureTypes = inputs().values().stream() + .collect(Collectors.toMap(input -> input.name(), input -> input.type())); allFields().forEach(field -> addAttributeFeatureTypes(field, featureTypes)); allImportedFields().forEach(field -> addAttributeFeatureTypes(field, featureTypes)); return featureTypes; @@ -1070,7 +1069,7 @@ public class RankProfile implements Cloneable { TensorType type = field.getType().asTensorType(); Optional<Reference> feature = Reference.simple(field.getName()); if ( feature.isEmpty() || ! feature.get().name().equals("query")) continue; - if (featureTypes.containsKey(feature)) continue; // Explicit feature types (from inputs) overrides + if (featureTypes.containsKey(feature.get())) continue; // Explicit feature types (from inputs) overrides TensorType existingType = context.getType(feature.get()); if ( ! Objects.equals(existingType, context.defaultTypeOf(feature.get()))) @@ -1392,6 +1391,46 @@ public class RankProfile implements Cloneable { } + public static final class Input { + + private final Reference name; + private final TensorType type; + private final Optional<Tensor> defaultValue; + + public Input(Reference name, TensorType type, Optional<Tensor> defaultValue) { + this.name = name; + this.type = type; + this.defaultValue = defaultValue; + } + + public Reference name() { return name; } + public TensorType type() { return type; } + public Optional<Tensor> defaultValue() { return defaultValue; } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if ( ! (o instanceof Input)) return false; + Input other = (Input)o; + if ( ! other.name().equals(this.name())) return false; + if ( ! other.type().equals(this.type())) return false; + if ( ! other.defaultValue().equals(this.defaultValue())) return false; + return true; + } + + @Override + public int hashCode() { + return Objects.hash(name, type, defaultValue); + } + + @Override + public String toString() { + return "input '" + name + "' " + type + + (defaultValue().isPresent() ? ":" + defaultValue.get().toAbbreviatedString() : ""); + } + + } + private static class CachedFunctions { private final Map<String, RankingExpressionFunction> allRankingExpressionFunctions; 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 3c14a2b9c63..77245da5ddd 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 @@ -145,7 +145,7 @@ public class RawRankProfile implements RankProfilesConfig.Producer { */ private final NativeRankTypeDefinitionSet nativeRankTypeDefinitions = new NativeRankTypeDefinitionSet("default"); private final Map<String, String> attributeTypes; - private final Map<Reference, TensorType> inputs; + private final Map<Reference, RankProfile.Input> inputs; private final Set<String> filterFields = new java.util.LinkedHashSet<>(); private final String rankprofileName; @@ -426,10 +426,16 @@ public class RawRankProfile implements RankProfilesConfig.Producer { for (Map.Entry<String, String> attributeType : attributeTypes.entrySet()) { properties.add(new Pair<>("vespa.type.attribute." + attributeType.getKey(), attributeType.getValue())); } - for (Map.Entry<Reference, TensorType> input : inputs.entrySet()) { - if (FeatureNames.isQueryFeature(input.getKey())) - properties.add(new Pair<>("vespa.type.query." + input.getKey().arguments().expressions().get(0), - input.getValue().toString())); + for (var input : inputs.values()) { + if (FeatureNames.isQueryFeature(input.name())) { + properties.add(new Pair<>("vespa.type.query." + input.name().arguments().expressions().get(0), + input.type().toString())); + if (input.defaultValue().isPresent()) + properties.add(new Pair<>(input.name().toString(), + input.type().rank() == 0 ? + String.valueOf(input.defaultValue().get().asDouble()) : + input.defaultValue().get().toString(false, false))); + } } if (properties.size() >= 1000000) throw new IllegalArgumentException("Too many rank properties"); distributeLargeExpressionsAsFiles(properties, largeRankExpressions); diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/SchemaInfo.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/SchemaInfo.java index eeb3a97eda9..0c1e5a76a89 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/SchemaInfo.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/SchemaInfo.java @@ -6,6 +6,7 @@ import com.yahoo.searchdefinition.RankProfile; import com.yahoo.searchdefinition.RankProfileRegistry; import com.yahoo.searchdefinition.Schema; import com.yahoo.searchlib.rankingexpression.Reference; +import com.yahoo.tensor.Tensor; import com.yahoo.tensor.TensorType; import com.yahoo.vespa.config.search.SummarymapConfig; import com.yahoo.vespa.documentmodel.SummaryTransform; @@ -15,6 +16,7 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Optional; /** * Information about a schema. @@ -100,7 +102,7 @@ public final class SchemaInfo extends Derived implements SchemaInfoConfig.Produc for (var input : rankProfile.inputs().entrySet()) { var inputConfig = new SchemaInfoConfig.Schema.Rankprofile.Input.Builder(); inputConfig.name(input.getKey().toString()); - inputConfig.type(input.getValue().toString()); + inputConfig.type(input.getValue().type().toString()); rankProfileConfig.input(inputConfig); } schemaBuilder.rankprofile(rankProfileConfig); @@ -113,7 +115,7 @@ public final class SchemaInfo extends Derived implements SchemaInfoConfig.Produc private final String name; private final boolean hasSummaryFeatures; private final boolean hasRankFeatures; - private final Map<Reference, TensorType> inputs; + private final Map<Reference, RankProfile.Input> inputs; public RankProfileInfo(RankProfile profile) { this.name = profile.name(); @@ -125,7 +127,7 @@ public final class SchemaInfo extends Derived implements SchemaInfoConfig.Produc public String name() { return name; } public boolean hasSummaryFeatures() { return hasSummaryFeatures; } public boolean hasRankFeatures() { return hasRankFeatures; } - public Map<Reference, TensorType> inputs() { return inputs; } + public Map<Reference, RankProfile.Input> inputs() { return inputs; } } 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 118945369d3..63a120f7c7b 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 @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.searchdefinition.parser; +import com.yahoo.searchdefinition.RankProfile; import com.yahoo.searchdefinition.RankProfile.MatchPhaseSettings; import com.yahoo.searchdefinition.RankProfile.MutateOperation; import com.yahoo.searchlib.rankingexpression.FeatureList; @@ -52,7 +53,7 @@ class ParsedRankProfile extends ParsedBlock { private final Map<String, String> fieldsRankType = new LinkedHashMap<>(); private final Map<String, List<String>> rankProperties = new LinkedHashMap<>(); private final Map<String, Value> constants = new LinkedHashMap<>(); - private final Map<Reference, TensorType> inputs = new LinkedHashMap<>(); + private final Map<Reference, RankProfile.Input> inputs = new LinkedHashMap<>(); ParsedRankProfile(String name) { super(name, "rank-profile"); @@ -83,7 +84,7 @@ class ParsedRankProfile extends ParsedBlock { Map<String, String> getFieldsWithRankType() { return Collections.unmodifiableMap(fieldsRankType); } Map<String, List<String>> getRankProperties() { return Collections.unmodifiableMap(rankProperties); } Map<String, Value> getConstants() { return Collections.unmodifiableMap(constants); } - Map<Reference, TensorType> getInputs() { return Collections.unmodifiableMap(inputs); } + Map<Reference, RankProfile.Input> getInputs() { return Collections.unmodifiableMap(inputs); } Optional<String> getInheritedSummaryFeatures() { return Optional.ofNullable(this.inheritedSummaryFeatures); } Optional<String> getSecondPhaseExpression() { return Optional.ofNullable(this.secondPhaseExpression); } @@ -110,9 +111,9 @@ class ParsedRankProfile extends ParsedBlock { constants.put(name, value); } - void addInput(Reference name, TensorType type) { + void addInput(Reference name, RankProfile.Input input) { verifyThat(! inputs.containsKey(name), "already has input", name); - inputs.put(name, type); + inputs.put(name, input); } void addFieldRankFilter(String field, boolean filter) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/multifieldresolver/RankProfileTypeSettingsProcessor.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/multifieldresolver/RankProfileTypeSettingsProcessor.java index 9de6a11ce44..fb7e67f2aab 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/multifieldresolver/RankProfileTypeSettingsProcessor.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/multifieldresolver/RankProfileTypeSettingsProcessor.java @@ -97,7 +97,8 @@ public class RankProfileTypeSettingsProcessor extends Processor { private void addQueryFeatureTypeToRankProfiles(Reference queryFeature, TensorType queryFeatureType) { for (RankProfile profile : rankProfileRegistry.all()) { if (! profile.inputs().containsKey(queryFeature)) // declared inputs have precedence - profile.addInput(queryFeature, queryFeatureType); + profile.addInput(queryFeature, + new RankProfile.Input(queryFeature, queryFeatureType, Optional.empty())); } } |