Skip to content

Commit ea7c8a2

Browse files
committed
addressing PR comments - fix for delayed dimensions provided when setting up a dense_vector field
1 parent bc7735b commit ea7c8a2

File tree

2 files changed

+59
-8
lines changed

2 files changed

+59
-8
lines changed

server/src/internalClusterTest/java/org/elasticsearch/index/mapper/DynamicMappingIT.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -914,8 +914,9 @@ public void testKnnSubObject() throws Exception {
914914
public void testDenseVectorDynamicMapping() throws Exception {
915915
assertAcked(indicesAdmin().prepareCreate("test").setMapping("""
916916
{
917-
"dynamic": "true"
918-
}""").get());
917+
"dynamic": "true"
918+
}
919+
""").get());
919920

920921
client().index(
921922
new IndexRequest("test").source("vector_int8", Randomness.get().doubles(BBQ_DIMS_DEFAULT_THRESHOLD - 1, 0.0, 5.0).toArray())
@@ -932,6 +933,35 @@ public void testDenseVectorDynamicMapping() throws Exception {
932933
assertTrue(new WriteField("properties.vector_int8.index_options.type", () -> mappings).get(null).toString().equals("int8_hnsw"));
933934
assertTrue(new WriteField("properties.vector_bbq", () -> mappings).exists());
934935
assertTrue(new WriteField("properties.vector_bbq.index_options.type", () -> mappings).get(null).toString().equals("bbq_hnsw"));
936+
}
937+
938+
public void testBBQDynamicMappingWhenFirstIngestingDoc() throws Exception {
939+
assertAcked(indicesAdmin().prepareCreate("test").setMapping("""
940+
{
941+
"properties": {
942+
"vector": {
943+
"type": "dense_vector"
944+
}
945+
}
946+
}
947+
""").get());
935948

949+
Map<String, Object> mappings = indicesAdmin().prepareGetMappings(TEST_REQUEST_TIMEOUT, "test")
950+
.get()
951+
.mappings()
952+
.get("test")
953+
.sourceAsMap();
954+
assertTrue(new WriteField("properties.vector", () -> mappings).exists());
955+
assertFalse(new WriteField("properties.vector.index_options.type", () -> mappings).exists());
956+
957+
client().index(new IndexRequest("test").source("vector", Randomness.get().doubles(BBQ_DIMS_DEFAULT_THRESHOLD, 0.0, 5.0).toArray()))
958+
.get();
959+
Map<String, Object> updatedMappings = indicesAdmin().prepareGetMappings(TEST_REQUEST_TIMEOUT, "test")
960+
.get()
961+
.mappings()
962+
.get("test")
963+
.sourceAsMap();
964+
assertTrue(new WriteField("properties.vector", () -> updatedMappings).exists());
965+
assertTrue(new WriteField("properties.vector.index_options.type", () -> updatedMappings).get(null).toString().equals("bbq_hnsw"));
936966
}
937967
}

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

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,8 @@ public Builder(String name, IndexVersion indexVersionCreated) {
350350
}
351351

352352
private DenseVectorIndexOptions defaultIndexOptions(boolean defaultInt8Hnsw, boolean defaultBBQHnsw) {
353-
if (elementType.getValue() == ElementType.FLOAT && this.indexed.getValue()) {
354-
if (defaultBBQHnsw && this.dims != null && this.dims.isConfigured() && this.dims.getValue() >= BBQ_DIMS_DEFAULT_THRESHOLD) {
353+
if (this.dims != null && this.dims.isConfigured() && elementType.getValue() == ElementType.FLOAT && this.indexed.getValue()) {
354+
if (defaultBBQHnsw && this.dims.getValue() >= BBQ_DIMS_DEFAULT_THRESHOLD) {
355355
return new BBQHnswIndexOptions(
356356
Lucene99HnswVectorsFormat.DEFAULT_MAX_CONN,
357357
Lucene99HnswVectorsFormat.DEFAULT_BEAM_WIDTH,
@@ -2713,8 +2713,29 @@ public void parse(DocumentParserContext context) throws IOException {
27132713
}
27142714
if (fieldType().dims == null) {
27152715
int dims = fieldType().elementType.parseDimensionCount(context);
2716-
if (fieldType().indexOptions != null) {
2717-
fieldType().indexOptions.validateDimension(dims);
2716+
IndexVersion indexVersionCreated = context.indexSettings().getIndexVersionCreated();
2717+
final boolean defaultInt8Hnsw = indexVersionCreated.onOrAfter(IndexVersions.DEFAULT_DENSE_VECTOR_TO_INT8_HNSW);
2718+
final boolean defaultBBQ8Hnsw = indexVersionCreated.onOrAfter(IndexVersions.DEFAULT_DENSE_VECTOR_TO_BBQ_HNSW);
2719+
DenseVectorIndexOptions denseVectorIndexOptions = fieldType().indexOptions;
2720+
if (denseVectorIndexOptions == null && fieldType().getElementType() == ElementType.FLOAT && fieldType().isIndexed()) {
2721+
if (defaultBBQ8Hnsw && dims >= BBQ_DIMS_DEFAULT_THRESHOLD) {
2722+
denseVectorIndexOptions = new BBQHnswIndexOptions(
2723+
Lucene99HnswVectorsFormat.DEFAULT_MAX_CONN,
2724+
Lucene99HnswVectorsFormat.DEFAULT_BEAM_WIDTH,
2725+
new RescoreVector(DEFAULT_OVERSAMPLE)
2726+
);
2727+
} else if (defaultInt8Hnsw) {
2728+
denseVectorIndexOptions = new Int8HnswIndexOptions(
2729+
Lucene99HnswVectorsFormat.DEFAULT_MAX_CONN,
2730+
Lucene99HnswVectorsFormat.DEFAULT_BEAM_WIDTH,
2731+
null,
2732+
null
2733+
);
2734+
}
2735+
}
2736+
;
2737+
if (denseVectorIndexOptions != null) {
2738+
denseVectorIndexOptions.validateDimension(dims);
27182739
}
27192740
DenseVectorFieldType updatedDenseVectorFieldType = new DenseVectorFieldType(
27202741
fieldType().name(),
@@ -2723,15 +2744,15 @@ public void parse(DocumentParserContext context) throws IOException {
27232744
dims,
27242745
fieldType().indexed,
27252746
fieldType().similarity,
2726-
fieldType().indexOptions,
2747+
denseVectorIndexOptions,
27272748
fieldType().meta(),
27282749
fieldType().isSyntheticSource
27292750
);
27302751
Mapper update = new DenseVectorFieldMapper(
27312752
leafName(),
27322753
updatedDenseVectorFieldType,
27332754
builderParams,
2734-
indexOptions,
2755+
denseVectorIndexOptions,
27352756
indexCreatedVersion
27362757
);
27372758
context.addDynamicMapper(update);

0 commit comments

Comments
 (0)