94
94
95
95
import static org .elasticsearch .common .Strings .format ;
96
96
import static org .elasticsearch .common .xcontent .XContentParserUtils .ensureExpectedToken ;
97
- import static org .elasticsearch .index .IndexVersions .DEFAULT_DENSE_VECTOR_TO_INT8_HNSW ;
98
- import static org .elasticsearch .index .IndexVersions .RESCORE_PARAMS_ALLOW_ZERO_TO_QUANTIZED_VECTORS ;
99
97
100
98
/**
101
99
* A {@link FieldMapper} for indexing a dense vector of floats.
@@ -118,21 +116,26 @@ private static boolean hasRescoreIndexVersion(IndexVersion version) {
118
116
}
119
117
120
118
private static boolean allowsZeroRescore (IndexVersion version ) {
121
- return version .onOrAfter (RESCORE_PARAMS_ALLOW_ZERO_TO_QUANTIZED_VECTORS );
119
+ return version .onOrAfter (IndexVersions .RESCORE_PARAMS_ALLOW_ZERO_TO_QUANTIZED_VECTORS );
120
+ }
121
+
122
+ private static boolean defaultOversampleForBBQ (IndexVersion version ) {
123
+ return version .onOrAfter (IndexVersions .DEFAULT_OVERSAMPLE_VALUE_FOR_BBQ_BACKPORT_8_X );
122
124
}
123
125
124
126
public static final IndexVersion MAGNITUDE_STORED_INDEX_VERSION = IndexVersions .V_7_5_0 ;
125
127
public static final IndexVersion INDEXED_BY_DEFAULT_INDEX_VERSION = IndexVersions .FIRST_DETACHED_INDEX_VERSION ;
126
128
public static final IndexVersion NORMALIZE_COSINE = IndexVersions .NORMALIZED_VECTOR_COSINE ;
127
- public static final IndexVersion DEFAULT_TO_INT8 = DEFAULT_DENSE_VECTOR_TO_INT8_HNSW ;
129
+ public static final IndexVersion DEFAULT_TO_INT8 = IndexVersions . DEFAULT_DENSE_VECTOR_TO_INT8_HNSW ;
128
130
public static final IndexVersion LITTLE_ENDIAN_FLOAT_STORED_INDEX_VERSION = IndexVersions .V_8_9_0 ;
129
- public static final IndexVersion RESCORE_PARAMS_ALLOW_ZERO_TO_QUANTIZED_VECTORS =
130
- IndexVersions .RESCORE_PARAMS_ALLOW_ZERO_TO_QUANTIZED_VECTORS ;
131
131
132
132
public static final NodeFeature RESCORE_VECTOR_QUANTIZED_VECTOR_MAPPING = new NodeFeature ("mapper.dense_vector.rescore_vector" );
133
133
public static final NodeFeature RESCORE_ZERO_VECTOR_QUANTIZED_VECTOR_MAPPING = new NodeFeature (
134
134
"mapper.dense_vector.rescore_zero_vector"
135
135
);
136
+ public static final NodeFeature USE_DEFAULT_OVERSAMPLE_VALUE_FOR_BBQ = new NodeFeature (
137
+ "mapper.dense_vector.default_oversample_value_for_bbq"
138
+ );
136
139
137
140
public static final String CONTENT_TYPE = "dense_vector" ;
138
141
public static short MAX_DIMS_COUNT = 4096 ; // maximum allowed number of dimensions
@@ -141,6 +144,7 @@ private static boolean allowsZeroRescore(IndexVersion version) {
141
144
public static short MIN_DIMS_FOR_DYNAMIC_FLOAT_MAPPING = 128 ; // minimum number of dims for floats to be dynamically mapped to vector
142
145
public static final int MAGNITUDE_BYTES = 4 ;
143
146
public static final int OVERSAMPLE_LIMIT = 10_000 ; // Max oversample allowed
147
+ public static final float DEFAULT_OVERSAMPLE = 3.0F ; // Default oversample value
144
148
145
149
private static DenseVectorFieldMapper toType (FieldMapper in ) {
146
150
return (DenseVectorFieldMapper ) in ;
@@ -196,7 +200,7 @@ public Builder(String name, IndexVersion indexVersionCreated) {
196
200
super (name );
197
201
this .indexVersionCreated = indexVersionCreated ;
198
202
final boolean indexedByDefault = indexVersionCreated .onOrAfter (INDEXED_BY_DEFAULT_INDEX_VERSION );
199
- final boolean defaultInt8Hnsw = indexVersionCreated .onOrAfter (DEFAULT_DENSE_VECTOR_TO_INT8_HNSW );
203
+ final boolean defaultInt8Hnsw = indexVersionCreated .onOrAfter (IndexVersions . DEFAULT_DENSE_VECTOR_TO_INT8_HNSW );
200
204
this .indexed = Parameter .indexParam (m -> toType (m ).fieldType ().indexed , indexedByDefault );
201
205
if (indexedByDefault ) {
202
206
// Only serialize on newer index versions to prevent breaking existing indices when upgrading
@@ -1439,6 +1443,9 @@ public IndexOptions parseIndexOptions(String fieldName, Map<String, ?> indexOpti
1439
1443
RescoreVector rescoreVector = null ;
1440
1444
if (hasRescoreIndexVersion (indexVersion )) {
1441
1445
rescoreVector = RescoreVector .fromIndexOptions (indexOptionsMap , indexVersion );
1446
+ if (rescoreVector == null && defaultOversampleForBBQ (indexVersion )) {
1447
+ rescoreVector = new RescoreVector (DEFAULT_OVERSAMPLE );
1448
+ }
1442
1449
}
1443
1450
MappingParser .checkNoRemainingFields (fieldName , indexOptionsMap );
1444
1451
return new BBQHnswIndexOptions (m , efConstruction , rescoreVector );
@@ -1460,6 +1467,9 @@ public IndexOptions parseIndexOptions(String fieldName, Map<String, ?> indexOpti
1460
1467
RescoreVector rescoreVector = null ;
1461
1468
if (hasRescoreIndexVersion (indexVersion )) {
1462
1469
rescoreVector = RescoreVector .fromIndexOptions (indexOptionsMap , indexVersion );
1470
+ if (rescoreVector == null && defaultOversampleForBBQ (indexVersion )) {
1471
+ rescoreVector = new RescoreVector (DEFAULT_OVERSAMPLE );
1472
+ }
1463
1473
}
1464
1474
MappingParser .checkNoRemainingFields (fieldName , indexOptionsMap );
1465
1475
return new BBQFlatIndexOptions (rescoreVector );
@@ -2288,6 +2298,10 @@ int getVectorDimensions() {
2288
2298
ElementType getElementType () {
2289
2299
return elementType ;
2290
2300
}
2301
+
2302
+ IndexOptions getIndexOptions () {
2303
+ return indexOptions ;
2304
+ }
2291
2305
}
2292
2306
2293
2307
private final IndexOptions indexOptions ;
0 commit comments