summaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/searchdefinition
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2022-05-09 12:37:14 +0200
committerJon Bratseth <bratseth@gmail.com>2022-05-09 12:37:14 +0200
commit8ac835c8d45b538c36be97ca3de545aa73c9d29d (patch)
treec0b511602ba1de4dda2f28307860226ab9093b23 /config-model/src/main/java/com/yahoo/searchdefinition
parent032aaa3611dd82bd9eaf2366c54babb47f81a9aa (diff)
Output input default values in rank properties
Diffstat (limited to 'config-model/src/main/java/com/yahoo/searchdefinition')
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java73
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/RawRankProfile.java16
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/SchemaInfo.java8
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedRankProfile.java9
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/processing/multifieldresolver/RankProfileTypeSettingsProcessor.java3
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()));
}
}