diff --git a/document/field_vector.go b/document/field_vector.go index 59ac02026..b019361cb 100644 --- a/document/field_vector.go +++ b/document/field_vector.go @@ -35,12 +35,13 @@ func init() { const DefaultVectorIndexingOptions = index.IndexField type VectorField struct { - name string - dims int // Dimensionality of the vector - similarity string // Similarity metric to use for scoring - options index.FieldIndexingOptions - value []float32 - numPlainTextBytes uint64 + name string + dims int // Dimensionality of the vector + similarity string // Similarity metric to use for scoring + options index.FieldIndexingOptions + value []float32 + numPlainTextBytes uint64 + vectorIndexOptimizedFor string // Optimization applied to this index. } func (n *VectorField) Size() int { @@ -95,25 +96,27 @@ func (n *VectorField) GoString() string { // For the sake of not polluting the API, we are keeping arrayPositions as a // parameter, but it is not used. func NewVectorField(name string, arrayPositions []uint64, - vector []float32, dims int, similarity string) *VectorField { + vector []float32, dims int, similarity, vectorIndexOptimizedFor string) *VectorField { return NewVectorFieldWithIndexingOptions(name, arrayPositions, - vector, dims, similarity, DefaultVectorIndexingOptions) + vector, dims, similarity, vectorIndexOptimizedFor, + DefaultVectorIndexingOptions) } // For the sake of not polluting the API, we are keeping arrayPositions as a // parameter, but it is not used. func NewVectorFieldWithIndexingOptions(name string, arrayPositions []uint64, - vector []float32, dims int, similarity string, + vector []float32, dims int, similarity, vectorIndexOptimizedFor string, options index.FieldIndexingOptions) *VectorField { options = options | DefaultVectorIndexingOptions return &VectorField{ - name: name, - dims: dims, - similarity: similarity, - options: options, - value: vector, - numPlainTextBytes: numBytesFloat32s(vector), + name: name, + dims: dims, + similarity: similarity, + options: options, + value: vector, + numPlainTextBytes: numBytesFloat32s(vector), + vectorIndexOptimizedFor: vectorIndexOptimizedFor, } } @@ -136,3 +139,7 @@ func (n *VectorField) Dims() int { func (n *VectorField) Similarity() string { return n.similarity } + +func (n *VectorField) IndexOptimizedFor() string { + return n.vectorIndexOptimizedFor +} diff --git a/mapping/field.go b/mapping/field.go index 8190c2ab1..a45787ef4 100644 --- a/mapping/field.go +++ b/mapping/field.go @@ -77,6 +77,9 @@ type FieldMapping struct { // vector fields. // See: index.DefaultSimilarityMetric & index.SupportedSimilarityMetrics Similarity string `json:"similarity,omitempty"` + + // The type of index based on the parameter to optimize for. + VectorIndexOptimizedFor string `json:"vector_index_optimized_for,omitempty"` } // NewTextFieldMapping returns a default field mapping for text @@ -466,6 +469,11 @@ func (fm *FieldMapping) UnmarshalJSON(data []byte) error { if err != nil { return err } + case "vector_index_optimized_for": + err := json.Unmarshal(v, &fm.VectorIndexOptimizedFor) + if err != nil { + return err + } default: invalidKeys = append(invalidKeys, k) } diff --git a/mapping/mapping_vectors.go b/mapping/mapping_vectors.go index 1e9268261..b1b30b644 100644 --- a/mapping/mapping_vectors.go +++ b/mapping/mapping_vectors.go @@ -132,7 +132,8 @@ func (fm *FieldMapping) processVector(propertyMightBeVector interface{}, fieldName := getFieldName(pathString, path, fm) options := fm.Options() field := document.NewVectorFieldWithIndexingOptions(fieldName, - indexes, vector, fm.Dims, fm.Similarity, options) + indexes, vector, fm.Dims, fm.Similarity, fm.VectorIndexOptimizedFor, + options) context.doc.AddField(field) // "_all" composite field is not applicable for vector field @@ -162,6 +163,11 @@ func validateVectorFieldAlias(field *FieldMapping, parentName string, field.Similarity = index.DefaultSimilarityMetric } + if field.VectorIndexOptimizedFor == "" { + fmt.Printf("using the default optimization type \n") + field.VectorIndexOptimizedFor = index.DefaultIndexOptimizedFor + } + // following fields are not applicable for vector // thus, we set them to default values field.IncludeInAll = false @@ -202,6 +208,12 @@ func validateVectorFieldAlias(field *FieldMapping, parentName string, reflect.ValueOf(index.SupportedSimilarityMetrics).MapKeys()) } + if _, ok := index.SupportedVectorIndexOptimizations[field.VectorIndexOptimizedFor]; !ok { + return fmt.Errorf("field: '%s', invalid optimization "+ + "metric: '%s', valid metrics are: %+v", field.Name, field.VectorIndexOptimizedFor, + reflect.ValueOf(index.SupportedVectorIndexOptimizations).MapKeys()) + } + if fieldAliasCtx != nil { // writing to a nil map is unsafe fieldAliasCtx[field.Name] = field }