Skip to content

Commit fc96ec3

Browse files
committed
Make dense_vector fields updatable to bbq_flat/bbq_hnsw
1 parent c3a1d58 commit fc96ec3

File tree

2 files changed

+206
-7
lines changed

2 files changed

+206
-7
lines changed

server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,7 +1664,9 @@ boolean updatableTo(IndexOptions update) {
16641664
|| update.type.equals(VectorIndexType.HNSW)
16651665
|| update.type.equals(VectorIndexType.INT8_HNSW)
16661666
|| update.type.equals(VectorIndexType.INT4_HNSW)
1667-
|| update.type.equals(VectorIndexType.INT4_FLAT);
1667+
|| update.type.equals(VectorIndexType.BBQ_HNSW)
1668+
|| update.type.equals(VectorIndexType.INT4_FLAT)
1669+
|| update.type.equals(VectorIndexType.BBQ_FLAT);
16681670
}
16691671
}
16701672

@@ -1778,7 +1780,8 @@ boolean updatableTo(IndexOptions update) {
17781780
// quantization could not behave as expected with different confidence intervals (and quantiles) to be created
17791781
updatable = int4HnswIndexOptions.m >= this.m && confidenceInterval == int4HnswIndexOptions.confidenceInterval;
17801782
}
1781-
return updatable;
1783+
return updatable
1784+
|| (update.type.equals(VectorIndexType.BBQ_HNSW) && ((BBQHnswIndexOptions) update).m >= m);
17821785
}
17831786
}
17841787

@@ -1834,7 +1837,9 @@ boolean updatableTo(IndexOptions update) {
18341837
return update.type.equals(this.type)
18351838
|| update.type.equals(VectorIndexType.HNSW)
18361839
|| update.type.equals(VectorIndexType.INT8_HNSW)
1837-
|| update.type.equals(VectorIndexType.INT4_HNSW);
1840+
|| update.type.equals(VectorIndexType.INT4_HNSW)
1841+
|| update.type.equals(VectorIndexType.BBQ_HNSW)
1842+
|| update.type.equals(VectorIndexType.BBQ_FLAT);
18381843
}
18391844

18401845
}
@@ -1916,7 +1921,8 @@ boolean updatableTo(IndexOptions update) {
19161921
|| int8HnswIndexOptions.confidenceInterval != null
19171922
&& confidenceInterval.equals(int8HnswIndexOptions.confidenceInterval);
19181923
} else {
1919-
updatable = update.type.equals(VectorIndexType.INT4_HNSW) && ((Int4HnswIndexOptions) update).m >= this.m;
1924+
updatable = update.type.equals(VectorIndexType.INT4_HNSW) && ((Int4HnswIndexOptions) update).m >= this.m
1925+
|| (update.type.equals(VectorIndexType.BBQ_HNSW) && ((BBQHnswIndexOptions) update).m >= m);
19201926
}
19211927
return updatable;
19221928
}
@@ -1950,7 +1956,8 @@ boolean updatableTo(IndexOptions update) {
19501956
}
19511957
return updatable
19521958
|| (update.type.equals(VectorIndexType.INT8_HNSW) && ((Int8HnswIndexOptions) update).m >= m)
1953-
|| (update.type.equals(VectorIndexType.INT4_HNSW) && ((Int4HnswIndexOptions) update).m >= m);
1959+
|| (update.type.equals(VectorIndexType.INT4_HNSW) && ((Int4HnswIndexOptions) update).m >= m)
1960+
|| (update.type.equals(VectorIndexType.BBQ_HNSW) && ((BBQHnswIndexOptions) update).m >= m);
19541961
}
19551962

19561963
@Override
@@ -2000,7 +2007,7 @@ KnnVectorsFormat getVectorsFormat(ElementType elementType) {
20002007

20012008
@Override
20022009
boolean updatableTo(IndexOptions update) {
2003-
return update.type.equals(this.type);
2010+
return update.type.equals(this.type) && ((BBQHnswIndexOptions) update).m >= this.m;
20042011
}
20052012

20062013
@Override
@@ -2054,7 +2061,7 @@ KnnVectorsFormat getVectorsFormat(ElementType elementType) {
20542061

20552062
@Override
20562063
boolean updatableTo(IndexOptions update) {
2057-
return update.type.equals(this.type);
2064+
return update.type.equals(this.type) || update.type.equals(VectorIndexType.BBQ_HNSW);
20582065
}
20592066

20602067
@Override

server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,36 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
275275
.endObject(),
276276
m -> assertTrue(m.toString().contains("\"type\":\"int4_hnsw\""))
277277
);
278+
checker.registerUpdateCheck(
279+
b -> b.field("type", "dense_vector")
280+
.field("dims", dims * 16)
281+
.field("index", true)
282+
.startObject("index_options")
283+
.field("type", "flat")
284+
.endObject(),
285+
b -> b.field("type", "dense_vector")
286+
.field("dims", dims * 16)
287+
.field("index", true)
288+
.startObject("index_options")
289+
.field("type", "bbq_flat")
290+
.endObject(),
291+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_flat\""))
292+
);
293+
checker.registerUpdateCheck(
294+
b -> b.field("type", "dense_vector")
295+
.field("dims", dims * 16)
296+
.field("index", true)
297+
.startObject("index_options")
298+
.field("type", "flat")
299+
.endObject(),
300+
b -> b.field("type", "dense_vector")
301+
.field("dims", dims * 16)
302+
.field("index", true)
303+
.startObject("index_options")
304+
.field("type", "bbq_hnsw")
305+
.endObject(),
306+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_hnsw\""))
307+
);
278308
// update for int8_flat
279309
checker.registerUpdateCheck(
280310
b -> b.field("type", "dense_vector")
@@ -355,6 +385,36 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
355385
.endObject()
356386
)
357387
);
388+
checker.registerUpdateCheck(
389+
b -> b.field("type", "dense_vector")
390+
.field("dims", dims * 16)
391+
.field("index", true)
392+
.startObject("index_options")
393+
.field("type", "int8_flat")
394+
.endObject(),
395+
b -> b.field("type", "dense_vector")
396+
.field("dims", dims * 16)
397+
.field("index", true)
398+
.startObject("index_options")
399+
.field("type", "bbq_flat")
400+
.endObject(),
401+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_flat\""))
402+
);
403+
checker.registerUpdateCheck(
404+
b -> b.field("type", "dense_vector")
405+
.field("dims", dims * 16)
406+
.field("index", true)
407+
.startObject("index_options")
408+
.field("type", "int8_flat")
409+
.endObject(),
410+
b -> b.field("type", "dense_vector")
411+
.field("dims", dims * 16)
412+
.field("index", true)
413+
.startObject("index_options")
414+
.field("type", "bbq_hnsw")
415+
.endObject(),
416+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_hnsw\""))
417+
);
358418
// update for hnsw
359419
checker.registerUpdateCheck(
360420
b -> b.field("type", "dense_vector")
@@ -480,6 +540,40 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
480540
.endObject()
481541
)
482542
);
543+
checker.registerConflictCheck(
544+
"index_options",
545+
fieldMapping(
546+
b -> b.field("type", "dense_vector")
547+
.field("dims", dims * 16)
548+
.field("index", true)
549+
.startObject("index_options")
550+
.field("type", "hnsw")
551+
.endObject()
552+
),
553+
fieldMapping(
554+
b -> b.field("type", "dense_vector")
555+
.field("dims", dims * 16)
556+
.field("index", true)
557+
.startObject("index_options")
558+
.field("type", "bbq_flat")
559+
.endObject()
560+
)
561+
);
562+
checker.registerUpdateCheck(
563+
b -> b.field("type", "dense_vector")
564+
.field("dims", dims * 16)
565+
.field("index", true)
566+
.startObject("index_options")
567+
.field("type", "hnsw")
568+
.endObject(),
569+
b -> b.field("type", "dense_vector")
570+
.field("dims", dims * 16)
571+
.field("index", true)
572+
.startObject("index_options")
573+
.field("type", "bbq_hnsw")
574+
.endObject(),
575+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_hnsw\""))
576+
);
483577
// update for int8_hnsw
484578
checker.registerUpdateCheck(
485579
b -> b.field("type", "dense_vector")
@@ -591,6 +685,40 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
591685
.endObject()
592686
)
593687
);
688+
checker.registerConflictCheck(
689+
"index_options",
690+
fieldMapping(
691+
b -> b.field("type", "dense_vector")
692+
.field("dims", dims * 16)
693+
.field("index", true)
694+
.startObject("index_options")
695+
.field("type", "int8_hnsw")
696+
.endObject()
697+
),
698+
fieldMapping(
699+
b -> b.field("type", "dense_vector")
700+
.field("dims", dims * 16)
701+
.field("index", true)
702+
.startObject("index_options")
703+
.field("type", "bbq_flat")
704+
.endObject()
705+
)
706+
);
707+
checker.registerUpdateCheck(
708+
b -> b.field("type", "dense_vector")
709+
.field("dims", dims * 16)
710+
.field("index", true)
711+
.startObject("index_options")
712+
.field("type", "int8_hnsw")
713+
.endObject(),
714+
b -> b.field("type", "dense_vector")
715+
.field("dims", dims * 16)
716+
.field("index", true)
717+
.startObject("index_options")
718+
.field("type", "bbq_hnsw")
719+
.endObject(),
720+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_hnsw\""))
721+
);
594722
// update for int4_flat
595723
checker.registerUpdateCheck(
596724
b -> b.field("type", "dense_vector")
@@ -677,6 +805,36 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
677805
.endObject()
678806
)
679807
);
808+
checker.registerUpdateCheck(
809+
b -> b.field("type", "dense_vector")
810+
.field("dims", dims * 16)
811+
.field("index", true)
812+
.startObject("index_options")
813+
.field("type", "int4_flat")
814+
.endObject(),
815+
b -> b.field("type", "dense_vector")
816+
.field("dims", dims * 16)
817+
.field("index", true)
818+
.startObject("index_options")
819+
.field("type", "bbq_flat")
820+
.endObject(),
821+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_flat\""))
822+
);
823+
checker.registerUpdateCheck(
824+
b -> b.field("type", "dense_vector")
825+
.field("dims", dims * 16)
826+
.field("index", true)
827+
.startObject("index_options")
828+
.field("type", "int4_flat")
829+
.endObject(),
830+
b -> b.field("type", "dense_vector")
831+
.field("dims", dims * 16)
832+
.field("index", true)
833+
.startObject("index_options")
834+
.field("type", "bbq_hnsw")
835+
.endObject(),
836+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_hnsw\""))
837+
);
680838
// update for int4_hnsw
681839
checker.registerUpdateCheck(
682840
b -> b.field("type", "dense_vector")
@@ -853,6 +1011,40 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
8531011
.endObject()
8541012
)
8551013
);
1014+
checker.registerConflictCheck(
1015+
"index_options",
1016+
fieldMapping(
1017+
b -> b.field("type", "dense_vector")
1018+
.field("dims", dims * 16)
1019+
.field("index", true)
1020+
.startObject("index_options")
1021+
.field("type", "int4_hnsw")
1022+
.endObject()
1023+
),
1024+
fieldMapping(
1025+
b -> b.field("type", "dense_vector")
1026+
.field("dims", dims * 16)
1027+
.field("index", true)
1028+
.startObject("index_options")
1029+
.field("type", "bbq_flat")
1030+
.endObject()
1031+
)
1032+
);
1033+
checker.registerUpdateCheck(
1034+
b -> b.field("type", "dense_vector")
1035+
.field("dims", dims * 16)
1036+
.field("index", true)
1037+
.startObject("index_options")
1038+
.field("type", "int4_hnsw")
1039+
.endObject(),
1040+
b -> b.field("type", "dense_vector")
1041+
.field("dims", dims * 16)
1042+
.field("index", true)
1043+
.startObject("index_options")
1044+
.field("type", "bbq_hnsw")
1045+
.endObject(),
1046+
m -> assertTrue(m.toString().contains("\"type\":\"bbq_hnsw\""))
1047+
);
8561048
}
8571049

8581050
@Override

0 commit comments

Comments
 (0)