summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeir Storli <geirst@verizonmedia.com>2020-05-12 15:52:15 +0000
committerGeir Storli <geirst@verizonmedia.com>2020-05-12 15:52:15 +0000
commitfe5a4c73f70cc451f461bc007d1ce7d32481edb2 (patch)
treebd8007d72484c81f11d43ca4a3ec0003f74d0bec
parent2d5ddf827dcef2af9619f8a9fee148f9edd12b02 (diff)
Support specifying a distance metric for nearest neighbor search when not having a hnsw index.
This also changes the syntax in the sd file to specifying the distance metric in the attribute tag.
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/Index.java17
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java1
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java7
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/AttributeOperation.java10
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/IndexOperation.java8
-rw-r--r--config-model/src/main/java/com/yahoo/searchdefinition/processing/TensorFieldProcessor.java1
-rw-r--r--config-model/src/main/javacc/SDParser.jj3
-rw-r--r--config-model/src/test/derived/advanced/attributes.cfg1
-rw-r--r--config-model/src/test/derived/array_of_struct_attribute/attributes.cfg2
-rw-r--r--config-model/src/test/derived/attributeprefetch/attributes.cfg18
-rw-r--r--config-model/src/test/derived/attributes/attributes.cfg18
-rw-r--r--config-model/src/test/derived/complex/attributes.cfg9
-rw-r--r--config-model/src/test/derived/hnsw_index/attributes.cfg27
-rw-r--r--config-model/src/test/derived/hnsw_index/ilscripts.cfg2
-rw-r--r--config-model/src/test/derived/hnsw_index/test.sd10
-rw-r--r--config-model/src/test/derived/imported_position_field/attributes.cfg2
-rw-r--r--config-model/src/test/derived/imported_struct_fields/attributes.cfg8
-rw-r--r--config-model/src/test/derived/importedfields/attributes.cfg8
-rw-r--r--config-model/src/test/derived/inheritance/attributes.cfg3
-rw-r--r--config-model/src/test/derived/inheritfromparent/attributes.cfg1
-rw-r--r--config-model/src/test/derived/map_attribute/attributes.cfg3
-rw-r--r--config-model/src/test/derived/map_of_struct_attribute/attributes.cfg5
-rw-r--r--config-model/src/test/derived/music/attributes.cfg11
-rw-r--r--config-model/src/test/derived/newrank/attributes.cfg10
-rw-r--r--config-model/src/test/derived/predicate_attribute/attributes.cfg1
-rw-r--r--config-model/src/test/derived/prefixexactattribute/attributes.cfg2
-rw-r--r--config-model/src/test/derived/reference_fields/attributes.cfg3
-rw-r--r--config-model/src/test/derived/sorting/attributes.cfg3
-rw-r--r--config-model/src/test/derived/tensor/attributes.cfg5
-rw-r--r--config-model/src/test/derived/types/attributes.cfg13
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java12
-rw-r--r--configdefinitions/src/vespa/attributes.def5
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/config.cpp3
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/config.h8
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h1
-rw-r--r--searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp17
-rw-r--r--searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/configconverter.cpp11
-rw-r--r--searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp3
39 files changed, 231 insertions, 42 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/Index.java b/config-model/src/main/java/com/yahoo/searchdefinition/Index.java
index aba6cf9a233..577639ead7a 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/Index.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/Index.java
@@ -24,8 +24,6 @@ import java.util.Set;
*/
public class Index implements Cloneable, Serializable {
- public static enum DistanceMetric { EUCLIDEAN, ANGULAR, GEODEGREES }
-
public enum Type {
VESPA("vespa");
@@ -65,8 +63,6 @@ public class Index implements Cloneable, Serializable {
private Optional<HnswIndexParams> hnswIndexParams = Optional.empty();
- private Optional<DistanceMetric> distanceMetric = Optional.empty();
-
/** Whether the posting lists of this index field should have interleaved features (num occs, field length) in document id stream. */
private boolean interleavedFeatures = false;
@@ -138,13 +134,12 @@ public class Index implements Cloneable, Serializable {
stemming == index.stemming &&
type == index.type &&
Objects.equals(boolIndex, index.boolIndex) &&
- Objects.equals(distanceMetric, index.distanceMetric) &&
Objects.equals(hnswIndexParams, index.hnswIndexParams);
}
@Override
public int hashCode() {
- return Objects.hash(name, rankType, prefix, aliases, stemming, normalized, type, boolIndex, distanceMetric, hnswIndexParams, interleavedFeatures);
+ return Objects.hash(name, rankType, prefix, aliases, stemming, normalized, type, boolIndex, hnswIndexParams, interleavedFeatures);
}
public String toString() {
@@ -192,16 +187,6 @@ public class Index implements Cloneable, Serializable {
boolIndex = def;
}
- public Optional<DistanceMetric> getDistanceMetric() {
- return distanceMetric;
- }
-
- public void setDistanceMetric(String value) {
- String upper = value.toUpperCase(Locale.ENGLISH);
- DistanceMetric dm = DistanceMetric.valueOf(upper);
- distanceMetric = Optional.of(dm);
- }
-
public Optional<HnswIndexParams> getHnswIndexParams() {
return hnswIndexParams;
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
index 8b5f7658475..004e44a7659 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/derived/AttributeFields.java
@@ -241,6 +241,7 @@ public class AttributeFields extends Derived implements AttributesConfig.Produce
}
aaB.imported(imported);
var dma = attribute.distanceMetric();
+ aaB.distancemetric(AttributesConfig.Attribute.Distancemetric.Enum.valueOf(dma.toString()));
if (attribute.hnswIndexParams().isPresent()) {
var ib = new AttributesConfig.Attribute.Index.Builder();
var params = attribute.hnswIndexParams().get();
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java b/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
index 1661a80f238..49d396327bf 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/document/Attribute.java
@@ -24,7 +24,6 @@ import com.yahoo.document.datatypes.Float16FieldValue;
import com.yahoo.document.datatypes.StringFieldValue;
import com.yahoo.document.datatypes.TensorFieldValue;
import com.yahoo.tensor.TensorType;
-import static com.yahoo.searchdefinition.Index.DistanceMetric;
import java.io.Serializable;
import java.util.LinkedHashSet;
@@ -40,6 +39,8 @@ import java.util.Set;
*/
public final class Attribute implements Cloneable, Serializable {
+ public enum DistanceMetric { EUCLIDEAN, ANGULAR, GEODEGREES }
+
// Remember to change hashCode and equals when you add new fields
private String name;
@@ -228,7 +229,7 @@ public final class Attribute implements Cloneable, Serializable {
public void setUpperBound(long upperBound) { this.upperBound = upperBound; }
public void setDensePostingListThreshold(double threshold) { this.densePostingListThreshold = threshold; }
public void setTensorType(TensorType tensorType) { this.tensorType = Optional.of(tensorType); }
- public void setDistanceMetric(Optional<DistanceMetric> dm) { this.distanceMetric = dm; }
+ public void setDistanceMetric(DistanceMetric metric) { this.distanceMetric = Optional.of(metric); }
public void setHnswIndexParams(HnswIndexParams params) { this.hnswIndexParams = Optional.of(params); }
public String getName() { return name; }
@@ -348,7 +349,7 @@ public final class Attribute implements Cloneable, Serializable {
public int hashCode() {
return Objects.hash(
name, type, collectionType, sorting, isPrefetch(), fastAccess, removeIfZero, createIfNonExistent,
- isPosition, huge, enableBitVectors, enableOnlyBitVector, tensorType, referenceDocumentType, hnswIndexParams);
+ isPosition, huge, enableBitVectors, enableOnlyBitVector, tensorType, referenceDocumentType, distanceMetric, hnswIndexParams);
}
@Override
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/AttributeOperation.java b/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/AttributeOperation.java
index 861a9f530d4..b638932a4a8 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/AttributeOperation.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/AttributeOperation.java
@@ -5,6 +5,7 @@ import com.yahoo.searchdefinition.document.Attribute;
import com.yahoo.searchdefinition.document.SDField;
import com.yahoo.tensor.TensorType;
+import java.util.Locale;
import java.util.Optional;
/**
@@ -24,6 +25,7 @@ public class AttributeOperation implements FieldOperation, FieldOperationContain
private String alias;
private String aliasedName;
private Optional<TensorType> tensorType = Optional.empty();
+ private Optional<String> distanceMetric = Optional.empty();
public AttributeOperation(String name) {
this.name = name;
@@ -116,6 +118,10 @@ public class AttributeOperation implements FieldOperation, FieldOperationContain
this.tensorType = Optional.of(tensorType);
}
+ public void setDistanceMetric(String value) {
+ this.distanceMetric = Optional.of(value);
+ }
+
public void apply(SDField field) {
Attribute attribute = null;
if (attributeIsSuffixOfStructField(field.getName())) {
@@ -153,6 +159,10 @@ public class AttributeOperation implements FieldOperation, FieldOperationContain
if (tensorType.isPresent()) {
attribute.setTensorType(tensorType.get());
}
+ if (distanceMetric.isPresent()) {
+ String upper = distanceMetric.get().toUpperCase(Locale.ENGLISH);
+ attribute.setDistanceMetric(Attribute.DistanceMetric.valueOf(upper));
+ }
}
private boolean attributeIsSuffixOfStructField(String fieldName) {
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/IndexOperation.java b/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/IndexOperation.java
index 0c1f443dee3..7f9da28b9ca 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/IndexOperation.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/fieldoperation/IndexOperation.java
@@ -32,7 +32,6 @@ public class IndexOperation implements FieldOperation {
private OptionalDouble densePostingListThreshold = OptionalDouble.empty();
private Optional<Boolean> enableBm25 = Optional.empty();
- private Optional<String> distanceMetric = Optional.empty();
private Optional<HnswIndexParams.Builder> hnswIndexParams = Optional.empty();
public String getIndexName() {
@@ -95,9 +94,6 @@ public class IndexOperation implements FieldOperation {
if (enableBm25.isPresent()) {
index.setInterleavedFeatures(enableBm25.get());
}
- if (distanceMetric.isPresent()) {
- index.setDistanceMetric(distanceMetric.get());
- }
if (hnswIndexParams.isPresent()) {
index.setHnswIndexParams(hnswIndexParams.get().build());
}
@@ -131,10 +127,6 @@ public class IndexOperation implements FieldOperation {
enableBm25 = Optional.of(value);
}
- public void setDistanceMetric(String value) {
- this.distanceMetric = Optional.of(value);
- }
-
public void setHnswIndexParams(HnswIndexParams.Builder params) {
this.hnswIndexParams = Optional.of(params);
}
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/TensorFieldProcessor.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/TensorFieldProcessor.java
index c97ee2bd935..8010be5043e 100644
--- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/TensorFieldProcessor.java
+++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/TensorFieldProcessor.java
@@ -83,7 +83,6 @@ public class TensorFieldProcessor extends Processor {
var params = new HnswIndexParams();
if (index != null) {
params = params.overrideFrom(index.getHnswIndexParams());
- field.getAttribute().setDistanceMetric(index.getDistanceMetric());
}
field.getAttribute().setHnswIndexParams(params);
}
diff --git a/config-model/src/main/javacc/SDParser.jj b/config-model/src/main/javacc/SDParser.jj
index 3560cf2cd84..043599dedbf 100644
--- a/config-model/src/main/javacc/SDParser.jj
+++ b/config-model/src/main/javacc/SDParser.jj
@@ -1212,6 +1212,7 @@ Object sortingSetting(SortingOperation sorting, String attributeName) :
*/
Object attributeSetting(FieldOperationContainer field, AttributeOperation attribute, String attributeName) :
{
+ String str;
}
{
(
@@ -1228,6 +1229,7 @@ Object attributeSetting(FieldOperationContainer field, AttributeOperation attrib
attribute.setAliasedName(aliasedName);
}
| attributeTensorType(attribute)
+ | <DISTANCEMETRIC> <COLON> str = identifierWithDash() { attribute.setDistanceMetric(str); }
)
{ return null; }
}
@@ -1816,7 +1818,6 @@ Object indexBody(IndexOperation index) :
| <UPPERBOUND> <COLON> num = consumeLong() { index.setUpperBound(num); }
| <DENSEPOSTINGLISTTHRESHOLD> <COLON> threshold = consumeFloat() { index.setDensePostingListThreshold(threshold); }
| <ENABLE_BM25> { index.setEnableBm25(true); }
- | <DISTANCEMETRIC> <COLON> str = identifierWithDash() { index.setDistanceMetric(str); }
| hnswIndex(index) { }
)
{ return null; }
diff --git a/config-model/src/test/derived/advanced/attributes.cfg b/config-model/src/test/derived/advanced/attributes.cfg
index 0a76e44c4ac..0217d957432 100644
--- a/config-model/src/test/derived/advanced/attributes.cfg
+++ b/config-model/src/test/derived/advanced/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/array_of_struct_attribute/attributes.cfg b/config-model/src/test/derived/array_of_struct_attribute/attributes.cfg
index 006400c09d4..8391a8a9bdd 100644
--- a/config-model/src/test/derived/array_of_struct_attribute/attributes.cfg
+++ b/config-model/src/test/derived/array_of_struct_attribute/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/attributeprefetch/attributes.cfg b/config-model/src/test/derived/attributeprefetch/attributes.cfg
index cd91c15700b..448f9a82d36 100644
--- a/config-model/src/test/derived/attributeprefetch/attributes.cfg
+++ b/config-model/src/test/derived/attributeprefetch/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -219,6 +227,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -244,6 +253,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -269,6 +279,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -294,6 +305,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -319,6 +331,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -344,6 +357,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -369,6 +383,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -394,6 +409,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -419,6 +435,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -444,6 +461,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/attributes/attributes.cfg b/config-model/src/test/derived/attributes/attributes.cfg
index 29e4c209ef2..d88c6b8b70a 100644
--- a/config-model/src/test/derived/attributes/attributes.cfg
+++ b/config-model/src/test/derived/attributes/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -219,6 +227,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -244,6 +253,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -269,6 +279,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -294,6 +305,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -319,6 +331,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -344,6 +357,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -369,6 +383,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -394,6 +409,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -419,6 +435,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -444,6 +461,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/complex/attributes.cfg b/config-model/src/test/derived/complex/attributes.cfg
index 5606e5ea730..337b736471d 100644
--- a/config-model/src/test/derived/complex/attributes.cfg
+++ b/config-model/src/test/derived/complex/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -219,6 +227,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/hnsw_index/attributes.cfg b/config-model/src/test/derived/hnsw_index/attributes.cfg
index b61fd7e2ee5..087a116f4cd 100644
--- a/config-model/src/test/derived/hnsw_index/attributes.cfg
+++ b/config-model/src/test/derived/hnsw_index/attributes.cfg
@@ -19,7 +19,34 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype "tensor(x[128])"
attribute[].imported false
+attribute[].distancemetric ANGULAR
attribute[].index.hnsw.enabled true
attribute[].index.hnsw.maxlinkspernode 32
attribute[].index.hnsw.distancemetric ANGULAR
attribute[].index.hnsw.neighborstoexploreatinsert 300
+attribute[].name "t2"
+attribute[].datatype TENSOR
+attribute[].collectiontype SINGLE
+attribute[].removeifzero false
+attribute[].createifnonexistent false
+attribute[].fastsearch false
+attribute[].huge false
+attribute[].ismutable false
+attribute[].sortascending true
+attribute[].sortfunction UCA
+attribute[].sortstrength PRIMARY
+attribute[].sortlocale ""
+attribute[].enablebitvectors false
+attribute[].enableonlybitvector false
+attribute[].fastaccess false
+attribute[].arity 8
+attribute[].lowerbound -9223372036854775808
+attribute[].upperbound 9223372036854775807
+attribute[].densepostinglistthreshold 0.4
+attribute[].tensortype "tensor(x[2])"
+attribute[].imported false
+attribute[].distancemetric GEODEGREES
+attribute[].index.hnsw.enabled false
+attribute[].index.hnsw.maxlinkspernode 16
+attribute[].index.hnsw.distancemetric EUCLIDEAN
+attribute[].index.hnsw.neighborstoexploreatinsert 200
diff --git a/config-model/src/test/derived/hnsw_index/ilscripts.cfg b/config-model/src/test/derived/hnsw_index/ilscripts.cfg
index e9fc265ca67..0c8266336b1 100644
--- a/config-model/src/test/derived/hnsw_index/ilscripts.cfg
+++ b/config-model/src/test/derived/hnsw_index/ilscripts.cfg
@@ -2,4 +2,6 @@ maxtermoccurrences 100
fieldmatchmaxlength 1000000
ilscript[].doctype "test"
ilscript[].docfield[] "t1"
+ilscript[].docfield[] "t2"
ilscript[].content[] "clear_state | guard { input t1 | attribute t1 | index t1; }"
+ilscript[].content[] "clear_state | guard { input t2 | attribute t2; }"
diff --git a/config-model/src/test/derived/hnsw_index/test.sd b/config-model/src/test/derived/hnsw_index/test.sd
index 207ed764a87..82291be9747 100644
--- a/config-model/src/test/derived/hnsw_index/test.sd
+++ b/config-model/src/test/derived/hnsw_index/test.sd
@@ -2,13 +2,21 @@ search test {
document test {
field t1 type tensor(x[128]) {
indexing: attribute | index
- index {
+ attribute {
distance-metric: angular
+ }
+ index {
hnsw {
max-links-per-node: 32
neighbors-to-explore-at-insert: 300
}
}
}
+ field t2 type tensor(x[2]) {
+ indexing: attribute
+ attribute {
+ distance-metric: geodegrees
+ }
+ }
}
}
diff --git a/config-model/src/test/derived/imported_position_field/attributes.cfg b/config-model/src/test/derived/imported_position_field/attributes.cfg
index 8f68068c8e7..685f708768a 100644
--- a/config-model/src/test/derived/imported_position_field/attributes.cfg
+++ b/config-model/src/test/derived/imported_position_field/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/imported_struct_fields/attributes.cfg b/config-model/src/test/derived/imported_struct_fields/attributes.cfg
index eb87c6cf53e..e8b7a7b6235 100644
--- a/config-model/src/test/derived/imported_struct_fields/attributes.cfg
+++ b/config-model/src/test/derived/imported_struct_fields/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/importedfields/attributes.cfg b/config-model/src/test/derived/importedfields/attributes.cfg
index d3a51523e05..6f3514102b4 100644
--- a/config-model/src/test/derived/importedfields/attributes.cfg
+++ b/config-model/src/test/derived/importedfields/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported true
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/inheritance/attributes.cfg b/config-model/src/test/derived/inheritance/attributes.cfg
index 397d8878792..541092622ff 100644
--- a/config-model/src/test/derived/inheritance/attributes.cfg
+++ b/config-model/src/test/derived/inheritance/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/inheritfromparent/attributes.cfg b/config-model/src/test/derived/inheritfromparent/attributes.cfg
index 3b30af10a8f..dda86f765be 100644
--- a/config-model/src/test/derived/inheritfromparent/attributes.cfg
+++ b/config-model/src/test/derived/inheritfromparent/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/map_attribute/attributes.cfg b/config-model/src/test/derived/map_attribute/attributes.cfg
index 4de78c52efd..702e065d15a 100644
--- a/config-model/src/test/derived/map_attribute/attributes.cfg
+++ b/config-model/src/test/derived/map_attribute/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/map_of_struct_attribute/attributes.cfg b/config-model/src/test/derived/map_of_struct_attribute/attributes.cfg
index 72e60b857a2..3eca0d5bbf8 100644
--- a/config-model/src/test/derived/map_of_struct_attribute/attributes.cfg
+++ b/config-model/src/test/derived/map_of_struct_attribute/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/music/attributes.cfg b/config-model/src/test/derived/music/attributes.cfg
index 4d19dc69b33..f75b8e06b80 100644
--- a/config-model/src/test/derived/music/attributes.cfg
+++ b/config-model/src/test/derived/music/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -219,6 +227,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -244,6 +253,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -269,6 +279,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/newrank/attributes.cfg b/config-model/src/test/derived/newrank/attributes.cfg
index 2aed2288773..303ea35223a 100644
--- a/config-model/src/test/derived/newrank/attributes.cfg
+++ b/config-model/src/test/derived/newrank/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -219,6 +227,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -244,6 +253,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/predicate_attribute/attributes.cfg b/config-model/src/test/derived/predicate_attribute/attributes.cfg
index 3a9daf7af94..d095b68752a 100644
--- a/config-model/src/test/derived/predicate_attribute/attributes.cfg
+++ b/config-model/src/test/derived/predicate_attribute/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 200
attribute[].densepostinglistthreshold 0.2
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/prefixexactattribute/attributes.cfg b/config-model/src/test/derived/prefixexactattribute/attributes.cfg
index 0a8cbd82186..5cae6b784ff 100644
--- a/config-model/src/test/derived/prefixexactattribute/attributes.cfg
+++ b/config-model/src/test/derived/prefixexactattribute/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/reference_fields/attributes.cfg b/config-model/src/test/derived/reference_fields/attributes.cfg
index e83b187a0cc..ec3ca030373 100644
--- a/config-model/src/test/derived/reference_fields/attributes.cfg
+++ b/config-model/src/test/derived/reference_fields/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/sorting/attributes.cfg b/config-model/src/test/derived/sorting/attributes.cfg
index 83c310ca5ca..6e50bd625ee 100644
--- a/config-model/src/test/derived/sorting/attributes.cfg
+++ b/config-model/src/test/derived/sorting/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/tensor/attributes.cfg b/config-model/src/test/derived/tensor/attributes.cfg
index 780f47ee3d5..6ed960728c2 100644
--- a/config-model/src/test/derived/tensor/attributes.cfg
+++ b/config-model/src/test/derived/tensor/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype "tensor<float>(x[2],y[1])"
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype "tensor(x{})"
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype "tensor(x[10],y[10])"
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype "tensor<float>(x[10])"
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/derived/types/attributes.cfg b/config-model/src/test/derived/types/attributes.cfg
index 82535324864..8e37a1f1c63 100644
--- a/config-model/src/test/derived/types/attributes.cfg
+++ b/config-model/src/test/derived/types/attributes.cfg
@@ -19,6 +19,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -44,6 +45,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -69,6 +71,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -94,6 +97,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -119,6 +123,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -144,6 +149,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -169,6 +175,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -194,6 +201,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -219,6 +227,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -244,6 +253,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -269,6 +279,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -294,6 +305,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
@@ -319,6 +331,7 @@ attribute[].upperbound 9223372036854775807
attribute[].densepostinglistthreshold 0.4
attribute[].tensortype ""
attribute[].imported false
+attribute[].distancemetric EUCLIDEAN
attribute[].index.hnsw.enabled false
attribute[].index.hnsw.maxlinkspernode 16
attribute[].index.hnsw.distancemetric EUCLIDEAN
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
index a704938610b..e32bd09bc08 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/search/AttributeChangeValidatorTest.java
@@ -168,10 +168,18 @@ public class AttributeChangeValidatorTest {
}
@Test
+ public void changing_distance_metric_without_hnsw_index_enabled_is_ok() throws Exception {
+ new Fixture("field f1 type tensor(x[2]) { indexing: attribute }",
+ "field f1 type tensor(x[2]) { indexing: attribute \n attribute { " +
+ "distance-metric: geodegrees \n } }").
+ assertValidation();
+ }
+
+ @Test
public void changing_distance_metric_with_hnsw_index_enabled_requires_restart() throws Exception {
new Fixture("field f1 type tensor(x[2]) { indexing: attribute | index \n index { hnsw } }",
- "field f1 type tensor(x[2]) { indexing: attribute | index \n index { " +
- "distance-metric: geodegrees \n hnsw } }").
+ "field f1 type tensor(x[2]) { indexing: attribute | index \n attribute { " +
+ "distance-metric: geodegrees \n } }").
assertValidation(newRestartAction("Field 'f1' changed: change property " +
"'distance-metric' from 'EUCLIDEAN' to 'GEODEGREES'"));
}
diff --git a/configdefinitions/src/vespa/attributes.def b/configdefinitions/src/vespa/attributes.def
index 604ddd40930..3602c2b0fd7 100644
--- a/configdefinitions/src/vespa/attributes.def
+++ b/configdefinitions/src/vespa/attributes.def
@@ -31,8 +31,13 @@ attribute[].tensortype string default=""
# Whether this is an imported attribute (from parent document db) or not.
attribute[].imported bool default=false
+# The distance metric to use for nearest neighbor search.
+# Is only used when the attribute is a 1-dimensional indexed tensor.
+attribute[].distancemetric enum { EUCLIDEAN, ANGULAR, GEODEGREES } default=EUCLIDEAN
+
# Configuration parameters for a hnsw index used together with a 1-dimensional indexed tensor for approximate nearest neighbor search.
attribute[].index.hnsw.enabled bool default=false
attribute[].index.hnsw.maxlinkspernode int default=16
+# Deprecated: Remove on Vespa 8 or before when possible.
attribute[].index.hnsw.distancemetric enum { EUCLIDEAN, ANGULAR, GEODEGREES } default=EUCLIDEAN
attribute[].index.hnsw.neighborstoexploreatinsert int default=200
diff --git a/searchcommon/src/vespa/searchcommon/attribute/config.cpp b/searchcommon/src/vespa/searchcommon/attribute/config.cpp
index b4e05875820..7752baa603a 100644
--- a/searchcommon/src/vespa/searchcommon/attribute/config.cpp
+++ b/searchcommon/src/vespa/searchcommon/attribute/config.cpp
@@ -18,6 +18,7 @@ Config::Config() :
_compactionStrategy(),
_predicateParams(),
_tensorType(vespalib::eval::ValueType::error_type()),
+ _distance_metric(DistanceMetric::Euclidean),
_hnsw_index_params()
{
}
@@ -36,6 +37,7 @@ Config::Config(BasicType bt, CollectionType ct, bool fastSearch_, bool huge_)
_compactionStrategy(),
_predicateParams(),
_tensorType(vespalib::eval::ValueType::error_type()),
+ _distance_metric(DistanceMetric::Euclidean),
_hnsw_index_params()
{
}
@@ -63,6 +65,7 @@ Config::operator==(const Config &b) const
_predicateParams == b._predicateParams &&
(_basicType.type() != BasicType::Type::TENSOR ||
_tensorType == b._tensorType) &&
+ _distance_metric == b._distance_metric &&
_hnsw_index_params == b._hnsw_index_params;
}
diff --git a/searchcommon/src/vespa/searchcommon/attribute/config.h b/searchcommon/src/vespa/searchcommon/attribute/config.h
index df5aa9e217a..822a4e4e028 100644
--- a/searchcommon/src/vespa/searchcommon/attribute/config.h
+++ b/searchcommon/src/vespa/searchcommon/attribute/config.h
@@ -9,6 +9,7 @@
#include <vespa/searchcommon/common/compaction_strategy.h>
#include <vespa/searchcommon/common/growstrategy.h>
#include <vespa/eval/eval/value_type.h>
+#include <cassert>
#include <optional>
namespace search::attribute {
@@ -35,6 +36,7 @@ public:
bool huge() const { return _huge; }
const PredicateParams &predicateParams() const { return _predicateParams; }
vespalib::eval::ValueType tensorType() const { return _tensorType; }
+ DistanceMetric distance_metric() const { return _distance_metric; }
const std::optional<HnswIndexParams>& hnsw_index_params() const { return _hnsw_index_params; }
/**
@@ -67,7 +69,12 @@ public:
_tensorType = tensorType_in;
return *this;
}
+ Config& set_distance_metric(DistanceMetric value) {
+ _distance_metric = value;
+ return *this;
+ }
Config& set_hnsw_index_params(const HnswIndexParams& params) {
+ assert(_distance_metric == params.distance_metric());
_hnsw_index_params = params;
return *this;
}
@@ -122,6 +129,7 @@ private:
CompactionStrategy _compactionStrategy;
PredicateParams _predicateParams;
vespalib::eval::ValueType _tensorType;
+ DistanceMetric _distance_metric;
std::optional<HnswIndexParams> _hnsw_index_params;
};
diff --git a/searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h b/searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h
index 94d3fda49f3..3e3683ce60f 100644
--- a/searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h
+++ b/searchcommon/src/vespa/searchcommon/attribute/hnsw_index_params.h
@@ -14,6 +14,7 @@ class HnswIndexParams {
private:
uint32_t _max_links_per_node;
uint32_t _neighbors_to_explore_at_insert;
+ // This is always the same as in the attribute config, and is duplicated here to simplify usage.
DistanceMetric _distance_metric;
public:
diff --git a/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp b/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp
index 1cb314165cd..3728b87c6df 100644
--- a/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp
+++ b/searchlib/src/tests/attribute/attributemanager/attributemanager_test.cpp
@@ -278,14 +278,25 @@ AttributeManagerTest::testConfigConvert()
AttributeVector::Config out = ConfigConverter::convert(a);
EXPECT_EQUAL("tensor(x[5])", out.tensorType().to_spec());
}
+ { // distance metric (default)
+ CACA a;
+ auto out = ConfigConverter::convert(a);
+ EXPECT_TRUE(out.distance_metric() == DistanceMetric::Euclidean);
+ }
+ { // distance metric (explicit)
+ CACA a;
+ a.distancemetric = AttributesConfig::Attribute::Distancemetric::GEODEGREES;
+ auto out = ConfigConverter::convert(a);
+ EXPECT_TRUE(out.distance_metric() == DistanceMetric::GeoDegrees);
+ }
{ // hnsw index params (enabled)
- auto dm_in = AttributesConfig::Attribute::Index::Hnsw::Distancemetric::ANGULAR;
- auto dm_out = search::attribute::DistanceMetric::Angular;
+ auto dm_in = AttributesConfig::Attribute::Distancemetric::ANGULAR;
+ auto dm_out = DistanceMetric::Angular;
CACA a;
+ a.distancemetric = dm_in;
a.index.hnsw.enabled = true;
a.index.hnsw.maxlinkspernode = 32;
a.index.hnsw.neighborstoexploreatinsert = 300;
- a.index.hnsw.distancemetric = dm_in;
auto out = ConfigConverter::convert(a);
EXPECT_TRUE(out.hnsw_index_params().has_value());
EXPECT_EQUAL(32u, out.hnsw_index_params().value().max_links_per_node());
diff --git a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp
index 18a6a5a8188..89093b6311f 100644
--- a/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp
+++ b/searchlib/src/tests/attribute/tensorattribute/tensorattribute_test.cpp
@@ -238,6 +238,7 @@ struct Fixture {
_useDenseTensorAttribute(useDenseTensorAttribute)
{
if (enable_hnsw_index) {
+ _cfg.set_distance_metric(DistanceMetric::Euclidean);
_cfg.set_hnsw_index_params(HnswIndexParams(4, 20, DistanceMetric::Euclidean));
}
setup();
diff --git a/searchlib/src/vespa/searchlib/attribute/configconverter.cpp b/searchlib/src/vespa/searchlib/attribute/configconverter.cpp
index c573f0b4210..f6c39b9570d 100644
--- a/searchlib/src/vespa/searchlib/attribute/configconverter.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/configconverter.cpp
@@ -73,10 +73,9 @@ ConfigConverter::convert(const AttributesConfig::Attribute & cfg)
predicateParams.setBounds(cfg.lowerbound, cfg.upperbound);
predicateParams.setDensePostingListThreshold(cfg.densepostinglistthreshold);
retval.setPredicateParams(predicateParams);
- if (cfg.index.hnsw.enabled) {
- using CfgDm = AttributesConfig::Attribute::Index::Hnsw::Distancemetric;
- DistanceMetric dm;
- switch (cfg.index.hnsw.distancemetric) {
+ using CfgDm = AttributesConfig::Attribute::Distancemetric;
+ DistanceMetric dm(DistanceMetric::Euclidean);
+ switch (cfg.distancemetric) {
case CfgDm::EUCLIDEAN:
dm = DistanceMetric::Euclidean;
break;
@@ -86,7 +85,9 @@ ConfigConverter::convert(const AttributesConfig::Attribute & cfg)
case CfgDm::GEODEGREES:
dm = DistanceMetric::GeoDegrees;
break;
- }
+ }
+ retval.set_distance_metric(dm);
+ if (cfg.index.hnsw.enabled) {
retval.set_hnsw_index_params(HnswIndexParams(cfg.index.hnsw.maxlinkspernode,
cfg.index.hnsw.neighborstoexploreatinsert,
dm));
diff --git a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp
index 68be4d35972..587f2ab7fcb 100644
--- a/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp
+++ b/searchlib/src/vespa/searchlib/queryeval/nearest_neighbor_blueprint.cpp
@@ -65,8 +65,7 @@ NearestNeighborBlueprint::NearestNeighborBlueprint(const queryeval::FieldSpec& f
auto rct = _attr_tensor.getTensorType().cell_type();
auto fixup_fun = vespalib::tensor::select_2<ConvertCellsSelector>(lct, rct);
fixup_fun(_query_tensor, _attr_tensor.getTensorType());
- auto def_dm = search::attribute::DistanceMetric::Euclidean;
- _fallback_dist_fun = search::tensor::make_distance_function(def_dm, rct);
+ _fallback_dist_fun = search::tensor::make_distance_function(_attr_tensor.getConfig().distance_metric(), rct);
_dist_fun = _fallback_dist_fun.get();
auto nns_index = _attr_tensor.nearest_neighbor_index();
if (nns_index) {