From 58a03e5f01cb96da9db21b08d589be0359953349 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Fri, 7 Nov 2025 14:30:26 +0000 Subject: [PATCH 01/13] Update docs on dense_vector for new types --- .../elasticsearch/mapping-reference/dense-vector.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/reference/elasticsearch/mapping-reference/dense-vector.md b/docs/reference/elasticsearch/mapping-reference/dense-vector.md index 1c81c1cc606fb..3ce26d87903b7 100644 --- a/docs/reference/elasticsearch/mapping-reference/dense-vector.md +++ b/docs/reference/elasticsearch/mapping-reference/dense-vector.md @@ -156,7 +156,7 @@ This setting is compatible with synthetic `_source`, where the entire `_source` ### Rehydration and precision -When vector values are rehydrated (e.g., for reindex, recovery, or explicit `_source` requests), they are restored from their internal format. Internally, vectors are stored at float precision, so if they were originally indexed as higher-precision types (e.g., `double` or `long`), the rehydrated values will have reduced precision. This lossy representation is intended to save space while preserving search quality. +When vector values are rehydrated (e.g., for reindex, recovery, or explicit `_source` requests), they are restored from their internal format. By default, vectors are stored at float precision, so if they were originally indexed as higher-precision types (e.g., `double` or `long`), the rehydrated values will have reduced precision. This lossy representation is intended to save space while preserving search quality. Additionally, using an `element_type` of `bfloat16` will cause a further loss in precision in restored vectors. ### Storing original vectors in `_source` @@ -283,12 +283,15 @@ The following mapping parameters are accepted: $$$dense-vector-element-type$$$ `element_type` -: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `byte`, and `bit`. +: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `bfloat16`, byte`, and `bit`. ::::{dropdown} Valid values for element_type `float` : indexes a 4-byte floating-point value per dimension. This is the default value. +`bfloat16` {applies_to}`stack: ga 9.3` +: indexes a 2-byte floating-point value per dimension. This uses the bfloat16 encoding, _not_ IEEE-754 float16, to maintain the same value range as 4-byte floats. Using `bfloat16` is likely to cause a loss of precision in the stored values compared to `float`. + `byte` : indexes a 1-byte integer value per dimension. @@ -362,7 +365,7 @@ $$$dense-vector-index-options$$$ * `int8_flat` - This utilizes a brute-force search algorithm in addition to automatic scalar quantization. Only supports `element_type` of `float`. * `int4_flat` - This utilizes a brute-force search algorithm in addition to automatic half-byte scalar quantization. Only supports `element_type` of `float`. * `bbq_flat` - This utilizes a brute-force search algorithm in addition to automatic binary quantization. Only supports `element_type` of `float`. - * {applies_to}`stack: ga 9.2` `bbq_disk` - This utilizes a variant of [k-means clustering algorithm](https://en.wikipedia.org/wiki/K-means_clustering) in addition to automatic binary quantization to partition vectors and search subspaces rather than an entire graph structure as in with HNSW. Only supports `element_type` of `float`. This combines the benefits of BBQ quantization with partitioning to further reduces the required memory overhead when compared with HNSW and can effectively be run at the smallest possible RAM and heap sizes when HNSW would otherwise cause swapping and grind to a halt. DiskBBQ largely scales linearly with the total RAM. And search performance is enhanced at scale as a subset of the total vector space is loaded. + * {applies_to}`stack: ga 9.2` `bbq_disk` - This utilizes a variant of [k-means clustering algorithm](https://en.wikipedia.org/wiki/K-means_clustering) in addition to automatic binary quantization to partition vectors and search subspaces rather than an entire graph structure as in with HNSW. Only supports `element_type` of `float` or `bfloat16`. This combines the benefits of BBQ quantization with partitioning to further reduces the required memory overhead when compared with HNSW and can effectively be run at the smallest possible RAM and heap sizes when HNSW would otherwise cause swapping and grind to a halt. DiskBBQ largely scales linearly with the total RAM. And search performance is enhanced at scale as a subset of the total vector space is loaded. `m` : (Optional, integer) The number of neighbors each node will be connected to in the HNSW graph. Defaults to `16`. Only applicable to `hnsw`, `int8_hnsw`, `int4_hnsw` and `bbq_hnsw` index types. @@ -390,6 +393,9 @@ $$$dense-vector-index-options$$$ : In case a knn query specifies a `rescore_vector` parameter, the query `rescore_vector` parameter will be used instead. : See [oversampling and rescoring quantized vectors](docs-content://solutions/search/vector/knn.md#dense-vector-knn-search-rescoring) for details. ::::: + +`on_disk_rescore` {applies_to}`stack: ga 9.3` {applies_to}`serverless: unavailable` +: (Optional, boolean) Only applicable to quantized index types. When `true`, vector rescoring will read the raw vector data directly from disk, and will not copy it in memory. This can improve performance when vector data is larger than the amount of available RAM. This setting only applies to newly-indexed vectors; after changing this setting, the vectors must be reindexed or force-merged to apply the new setting to the whole index. Defaults to `false`. :::: From 5ee9ea19e98b959243e6382ea72a759416ffc06d Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Mon, 24 Nov 2025 11:27:27 +0000 Subject: [PATCH 02/13] Remove feature flag --- .../rest/yaml/CcsCommonYamlTestSuiteIT.java | 3 +- .../yaml/RcsCcsCommonYamlTestSuiteIT.java | 1 - ...okeTestMultiNodeClientYamlTestSuiteIT.java | 1 - .../test/rest/ClientYamlTestSuiteIT.java | 1 - .../elasticsearch/index/store/DirectIOIT.java | 3 - .../es93/ES93GenericFlatVectorsFormat.java | 3 - .../index/mapper/MapperFeatures.java | 12 +- .../vectors/DenseVectorFieldMapper.java | 88 +++------ .../vectors/DenseVectorFieldMapperTests.java | 179 ++++++------------ .../test/cluster/FeatureFlag.java | 1 - ...CoreWithSecurityClientYamlTestSuiteIT.java | 1 - 11 files changed, 80 insertions(+), 213 deletions(-) diff --git a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java index f517e52ce423a..7b7fa6b4ab6d1 100644 --- a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java +++ b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java @@ -96,8 +96,7 @@ public class CcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase { // geohex_grid requires gold license .setting("xpack.license.self_generated.type", "trial") .feature(FeatureFlag.TIME_SERIES_MODE) - .feature(FeatureFlag.SYNTHETIC_VECTORS) - .feature(FeatureFlag.GENERIC_VECTOR_FORMAT); + .feature(FeatureFlag.SYNTHETIC_VECTORS); private static ElasticsearchCluster remoteCluster = ElasticsearchCluster.local() .name(REMOTE_CLUSTER_NAME) diff --git a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java index 7d1ed9d92238a..e5362c31f32f9 100644 --- a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java +++ b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java @@ -96,7 +96,6 @@ public class RcsCcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase { .setting("xpack.security.remote_cluster_client.ssl.enabled", "false") .feature(FeatureFlag.TIME_SERIES_MODE) .feature(FeatureFlag.SYNTHETIC_VECTORS) - .feature(FeatureFlag.GENERIC_VECTOR_FORMAT) .user("test_admin", "x-pack-test-password"); private static ElasticsearchCluster fulfillingCluster = ElasticsearchCluster.local() diff --git a/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java b/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java index 8af1760f2ebd3..529d7a7155264 100644 --- a/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java +++ b/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java @@ -38,7 +38,6 @@ public class SmokeTestMultiNodeClientYamlTestSuiteIT extends ESClientYamlSuiteTe .feature(FeatureFlag.DOC_VALUES_SKIPPER) .feature(FeatureFlag.SYNTHETIC_VECTORS) .feature(FeatureFlag.RANDOM_SAMPLING) - .feature(FeatureFlag.GENERIC_VECTOR_FORMAT) .build(); public SmokeTestMultiNodeClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { diff --git a/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java b/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java index 45b049784c380..2cebc6a743703 100644 --- a/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java +++ b/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java @@ -38,7 +38,6 @@ public class ClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase { .feature(FeatureFlag.DOC_VALUES_SKIPPER) .feature(FeatureFlag.SYNTHETIC_VECTORS) .feature(FeatureFlag.RANDOM_SAMPLING) - .feature(FeatureFlag.GENERIC_VECTOR_FORMAT) .build(); public ClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { diff --git a/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java b/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java index a85a435408402..6cad195049fe5 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java @@ -20,7 +20,6 @@ import org.apache.lucene.tests.util.LuceneTestCase; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.Strings; -import org.elasticsearch.index.codec.vectors.es93.ES93GenericFlatVectorsFormat; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.search.vectors.KnnSearchBuilder; import org.elasticsearch.search.vectors.VectorData; @@ -60,8 +59,6 @@ public static void checkSupported() { } catch (IOException e) { SUPPORTED = false; } - - assumeTrue("Generic format supporting direct IO not enabled", ES93GenericFlatVectorsFormat.GENERIC_VECTOR_FORMAT.isEnabled()); } static DirectIODirectory open(Path path) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/index/codec/vectors/es93/ES93GenericFlatVectorsFormat.java b/server/src/main/java/org/elasticsearch/index/codec/vectors/es93/ES93GenericFlatVectorsFormat.java index d2278bc0f30bf..0eedc3f16cdfb 100644 --- a/server/src/main/java/org/elasticsearch/index/codec/vectors/es93/ES93GenericFlatVectorsFormat.java +++ b/server/src/main/java/org/elasticsearch/index/codec/vectors/es93/ES93GenericFlatVectorsFormat.java @@ -15,7 +15,6 @@ import org.apache.lucene.codecs.hnsw.FlatVectorsWriter; import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.index.SegmentWriteState; -import org.elasticsearch.common.util.FeatureFlag; import org.elasticsearch.index.codec.vectors.AbstractFlatVectorsFormat; import org.elasticsearch.index.codec.vectors.DirectIOCapableFlatVectorsFormat; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; @@ -25,8 +24,6 @@ public class ES93GenericFlatVectorsFormat extends AbstractFlatVectorsFormat { - public static final FeatureFlag GENERIC_VECTOR_FORMAT = new FeatureFlag("generic_vector_format"); - static final String NAME = "ES93GenericFlatVectorsFormat"; static final String VECTOR_FORMAT_INFO_EXTENSION = "vfi"; static final String META_CODEC_NAME = "ES93GenericFlatVectorsFormatMeta"; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java b/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java index ae40e8d1c696a..8f096b05cc0f1 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java @@ -11,9 +11,7 @@ import org.elasticsearch.features.FeatureSpecification; import org.elasticsearch.features.NodeFeature; -import org.elasticsearch.index.codec.vectors.es93.ES93GenericFlatVectorsFormat; -import java.util.HashSet; import java.util.Set; import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.RESCORE_VECTOR_QUANTIZED_VECTOR_MAPPING; @@ -67,7 +65,7 @@ public class MapperFeatures implements FeatureSpecification { @Override public Set getTestFeatures() { - var features = Set.of( + return Set.of( RangeFieldMapper.DATE_RANGE_INDEXING_FIX, IgnoredSourceFieldMapper.DONT_EXPAND_DOTS_IN_IGNORED_SOURCE, SourceFieldMapper.REMOVE_SYNTHETIC_SOURCE_ONLY_VALIDATION, @@ -108,12 +106,8 @@ public Set getTestFeatures() { EXCLUDE_VECTORS_DOCVALUE_BUGFIX, BASE64_DENSE_VECTORS, FIX_DENSE_VECTOR_WRONG_FIELDS, - BBQ_DISK_STATS_SUPPORT + BBQ_DISK_STATS_SUPPORT, + GENERIC_VECTOR_FORMAT ); - if (ES93GenericFlatVectorsFormat.GENERIC_VECTOR_FORMAT.isEnabled()) { - features = new HashSet<>(features); - features.add(GENERIC_VECTOR_FORMAT); - } - return features; } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java index 112ca683ef078..fbe7802efb354 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java @@ -49,18 +49,12 @@ import org.elasticsearch.index.IndexVersion; import org.elasticsearch.index.IndexVersions; import org.elasticsearch.index.codec.vectors.BFloat16; -import org.elasticsearch.index.codec.vectors.ES813FlatVectorFormat; -import org.elasticsearch.index.codec.vectors.ES813Int8FlatVectorFormat; -import org.elasticsearch.index.codec.vectors.ES814HnswScalarQuantizedVectorsFormat; import org.elasticsearch.index.codec.vectors.ES815BitFlatVectorFormat; import org.elasticsearch.index.codec.vectors.ES815HnswBitVectorsFormat; import org.elasticsearch.index.codec.vectors.diskbbq.ES920DiskBBQVectorsFormat; import org.elasticsearch.index.codec.vectors.diskbbq.next.ESNextDiskBBQVectorsFormat; -import org.elasticsearch.index.codec.vectors.es818.ES818BinaryQuantizedVectorsFormat; -import org.elasticsearch.index.codec.vectors.es818.ES818HnswBinaryQuantizedVectorsFormat; import org.elasticsearch.index.codec.vectors.es93.ES93BinaryQuantizedVectorsFormat; import org.elasticsearch.index.codec.vectors.es93.ES93FlatVectorFormat; -import org.elasticsearch.index.codec.vectors.es93.ES93GenericFlatVectorsFormat; import org.elasticsearch.index.codec.vectors.es93.ES93HnswBinaryQuantizedVectorsFormat; import org.elasticsearch.index.codec.vectors.es93.ES93HnswScalarQuantizedVectorsFormat; import org.elasticsearch.index.codec.vectors.es93.ES93HnswVectorsFormat; @@ -490,25 +484,16 @@ public String toString() { public static final Element BFLOAT16_ELEMENT = new BFloat16Element(); public static final Element BIT_ELEMENT = new BitElement(); - public static final Map namesToElementType = ES93GenericFlatVectorsFormat.GENERIC_VECTOR_FORMAT.isEnabled() - ? Map.of( - ElementType.BYTE.toString(), - ElementType.BYTE, - ElementType.FLOAT.toString(), - ElementType.FLOAT, - ElementType.BFLOAT16.toString(), - ElementType.BFLOAT16, - ElementType.BIT.toString(), - ElementType.BIT - ) - : Map.of( - ElementType.BYTE.toString(), - ElementType.BYTE, - ElementType.FLOAT.toString(), - ElementType.FLOAT, - ElementType.BIT.toString(), - ElementType.BIT - ); + public static final Map namesToElementType = Map.of( + ElementType.BYTE.toString(), + ElementType.BYTE, + ElementType.FLOAT.toString(), + ElementType.FLOAT, + ElementType.BFLOAT16.toString(), + ElementType.BFLOAT16, + ElementType.BIT.toString(), + ElementType.BIT + ); public abstract static class Element { @@ -1516,9 +1501,7 @@ public DenseVectorIndexOptions parseIndexOptions(String fieldName, Map indexOptionsMap, IndexVersion indexVersion) { Object mNode = indexOptionsMap.remove("m"); Object efConstructionNode = indexOptionsMap.remove("ef_construction"); - Object onDiskRescoreNode = ES93GenericFlatVectorsFormat.GENERIC_VECTOR_FORMAT.isEnabled() - ? indexOptionsMap.remove("on_disk_rescore") - : false; + Object onDiskRescoreNode = indexOptionsMap.remove("on_disk_rescore"); int m = XContentMapValues.nodeIntegerValue(mNode, Lucene99HnswVectorsFormat.DEFAULT_MAX_CONN); int efConstruction = XContentMapValues.nodeIntegerValue(efConstructionNode, Lucene99HnswVectorsFormat.DEFAULT_BEAM_WIDTH); @@ -1749,9 +1728,7 @@ public DenseVectorIndexOptions parseIndexOptions(String fieldName, Map Date: Mon, 24 Nov 2025 11:33:32 +0000 Subject: [PATCH 03/13] Doc updates --- .../mapping-reference/dense-vector.md | 18 +++++++++--------- .../mapper/vectors/DenseVectorFieldMapper.java | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/reference/elasticsearch/mapping-reference/dense-vector.md b/docs/reference/elasticsearch/mapping-reference/dense-vector.md index 3ce26d87903b7..e47edf8f57300 100644 --- a/docs/reference/elasticsearch/mapping-reference/dense-vector.md +++ b/docs/reference/elasticsearch/mapping-reference/dense-vector.md @@ -283,7 +283,7 @@ The following mapping parameters are accepted: $$$dense-vector-element-type$$$ `element_type` -: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `bfloat16`, byte`, and `bit`. +: (Optional, string) The data type used to encode vectors. The supported data types are `float` (default), `bfloat16`, `byte`, and `bit`. ::::{dropdown} Valid values for element_type `float` @@ -356,15 +356,15 @@ $$$dense-vector-index-options$$$ * `int8_hnsw` - The default index type for some float vectors: * {applies_to}`stack: ga 9.1` Default for float vectors with less than 384 dimensions. * {applies_to}`stack: ga 9.0` Default for float all vectors. - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float`. This can reduce the memory footprint by 4x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). - * `int4_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float`. This can reduce the memory footprint by 8x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). - * `bbq_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically binary quantization for scalable approximate kNN search with `element_type` of `float`. This can reduce the memory footprint by 32x at the cost of accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). + This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16`. This can reduce the memory footprint by 4x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). + * `int4_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16` . This can reduce the memory footprint by 8x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). + * `bbq_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically binary quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16` . This can reduce the memory footprint by 32x at the cost of accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). {applies_to}`stack: ga 9.1` `bbq_hnsw` is the default index type for float vectors with greater than or equal to 384 dimensions. * `flat` - This utilizes a brute-force search algorithm for exact kNN search. This supports all `element_type` values. - * `int8_flat` - This utilizes a brute-force search algorithm in addition to automatic scalar quantization. Only supports `element_type` of `float`. - * `int4_flat` - This utilizes a brute-force search algorithm in addition to automatic half-byte scalar quantization. Only supports `element_type` of `float`. - * `bbq_flat` - This utilizes a brute-force search algorithm in addition to automatic binary quantization. Only supports `element_type` of `float`. + * `int8_flat` - This utilizes a brute-force search algorithm in addition to automatic scalar quantization. Only supports `element_type` of `float` or `bfloat16`. + * `int4_flat` - This utilizes a brute-force search algorithm in addition to automatic half-byte scalar quantization. Only supports `element_type` of `float` or `bfloat16`. + * `bbq_flat` - This utilizes a brute-force search algorithm in addition to automatic binary quantization. Only supports `element_type` of `float` or `bfloat16`. * {applies_to}`stack: ga 9.2` `bbq_disk` - This utilizes a variant of [k-means clustering algorithm](https://en.wikipedia.org/wiki/K-means_clustering) in addition to automatic binary quantization to partition vectors and search subspaces rather than an entire graph structure as in with HNSW. Only supports `element_type` of `float` or `bfloat16`. This combines the benefits of BBQ quantization with partitioning to further reduces the required memory overhead when compared with HNSW and can effectively be run at the smallest possible RAM and heap sizes when HNSW would otherwise cause swapping and grind to a halt. DiskBBQ largely scales linearly with the total RAM. And search performance is enhanced at scale as a subset of the total vector space is loaded. `m` @@ -394,8 +394,8 @@ $$$dense-vector-index-options$$$ : See [oversampling and rescoring quantized vectors](docs-content://solutions/search/vector/knn.md#dense-vector-knn-search-rescoring) for details. ::::: -`on_disk_rescore` {applies_to}`stack: ga 9.3` {applies_to}`serverless: unavailable` -: (Optional, boolean) Only applicable to quantized index types. When `true`, vector rescoring will read the raw vector data directly from disk, and will not copy it in memory. This can improve performance when vector data is larger than the amount of available RAM. This setting only applies to newly-indexed vectors; after changing this setting, the vectors must be reindexed or force-merged to apply the new setting to the whole index. Defaults to `false`. +`on_disk_rescore` {applies_to}`stack: preview 9.3` {applies_to}`serverless: unavailable` +: (Optional, boolean) Only applicable to quantized HNSW and `bbq_disk` index types. When `true`, vector rescoring will read the raw vector data directly from disk, and will not copy it in memory. This can improve performance when vector data is larger than the amount of available RAM. This setting only applies to newly-indexed vectors; after changing this setting, the vectors must be reindexed or force-merged to apply the new setting to the whole index. Defaults to `false`. :::: diff --git a/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java index fbe7802efb354..b1f7a88191f56 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java @@ -1918,7 +1918,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.field("ef_construction", efConstruction); builder.field("confidence_interval", confidenceInterval); if (onDiskRescore) { - builder.field("on_disk_rescore", onDiskRescore); + builder.field("on_disk_rescore", true); } if (rescoreVector != null) { rescoreVector.toXContent(builder, params); From 492b5aa52745dcf5354221fffb78cd1bdd99c9e0 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Mon, 24 Nov 2025 11:36:03 +0000 Subject: [PATCH 04/13] Update docs/changelog/138492.yaml --- docs/changelog/138492.yaml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/changelog/138492.yaml diff --git a/docs/changelog/138492.yaml b/docs/changelog/138492.yaml new file mode 100644 index 0000000000000..5197a492785d1 --- /dev/null +++ b/docs/changelog/138492.yaml @@ -0,0 +1,5 @@ +pr: 138492 +summary: Enable bfloat16 and on-disk rescoring for dense vectors +area: Vector Search +type: feature +issues: [] From 74987de3a4d6394fe52fd3981664b082b57c1dfb Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Mon, 24 Nov 2025 11:46:14 +0000 Subject: [PATCH 05/13] Update docs/changelog/138492.yaml --- docs/changelog/138492.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/changelog/138492.yaml b/docs/changelog/138492.yaml index 5197a492785d1..6bc2fc66a6d60 100644 --- a/docs/changelog/138492.yaml +++ b/docs/changelog/138492.yaml @@ -3,3 +3,9 @@ summary: Enable bfloat16 and on-disk rescoring for dense vectors area: Vector Search type: feature issues: [] +highlight: + title: Enable bfloat16 and on-disk rescoring for dense vectors + body: |- + Remove the feature flag for `bfloat16` and `on_disk_rescore`. `bfloat16` + is marked as GA for 9.3, `on_disk_rescore` is in preview for now. + notable: true From a44267b3eb43d6ab2226b3df0f02b11843100eb2 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Mon, 24 Nov 2025 13:28:37 +0000 Subject: [PATCH 06/13] Docs --- docs/changelog/138492.yaml | 57 +++++++++++++++++-- .../mapping-reference/dense-vector.md | 4 +- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/docs/changelog/138492.yaml b/docs/changelog/138492.yaml index 6bc2fc66a6d60..e163e5c15cb35 100644 --- a/docs/changelog/138492.yaml +++ b/docs/changelog/138492.yaml @@ -4,8 +4,57 @@ area: Vector Search type: feature issues: [] highlight: - title: Enable bfloat16 and on-disk rescoring for dense vectors - body: |- - Remove the feature flag for `bfloat16` and `on_disk_rescore`. `bfloat16` - is marked as GA for 9.3, `on_disk_rescore` is in preview for now. notable: true + title: New dense_vector options for storing bfloat16 vectors and utilising on-disk rescoring + body: |- + New options have been added to the `dense_vector` field type. + + The first is support for storing vectors in https://en.wikipedia.org/wiki/Bfloat16_floating-point_format[bfloat16] + format. This is a floating-point format that utilises 2-bytes per value rather than 4, halving the storage space + required compared to `element_type: float`. This can be specified with `element_type: bfloat16` + when creating the index, for all `dense_vector` indexing types: + + [source,yaml] + ---------------------------- + PUT vectors + { + "mappings": { + "properties": { + "vector": { + "type": "dense_vector", + "element_type": "bfloat16", + "index_options": {"type": "bbq_hnsw"} + } + } + } + ---------------------------- + + Float values are automatically truncated to 2-bytes when writing to disk, so this format can be used + with original source vectors at 2- or 4-byte precision. BFloat16 values are zero-expanded back to 4-byte floats + when read into memory. Using `bfloat16` will cause a loss of precision compared to + the original vector values, as well as a small performance hit due to converting between `bfloat16` and `float` + when reading and writing vectors; however this may be counterbalanced by a corresponding decrease in I/O, + depending on your workload. + + The second option is to utilise on-disk rescoring. When rescoring vectors during kNN searches, the raw vectors + are read into memory. When the vector data is larger than the amount of available RAM, this might cause the OS + to evict some in-memory pages that then need to be paged back in immediately afterwards. This can cause + a significant slowdown in search speed. Utilising on-disk rescoring causes rescoring to use raw vector data + on-disk during rescoring, and to not read it into memory first. This may significantly increase search performance + in such low-memory situations. + + This is specified as an index option for HNSW vector index types: + + [source,yaml] + ---------------------------- + PUT vectors + { + "mappings": { + "properties": { + "vector": { + "type": "dense_vector", + "index_options": {"type": "bbq_hnsw", "on_disk_rescore": true} + } + } + } + ---------------------------- diff --git a/docs/reference/elasticsearch/mapping-reference/dense-vector.md b/docs/reference/elasticsearch/mapping-reference/dense-vector.md index e47edf8f57300..ecc58c648832e 100644 --- a/docs/reference/elasticsearch/mapping-reference/dense-vector.md +++ b/docs/reference/elasticsearch/mapping-reference/dense-vector.md @@ -357,8 +357,8 @@ $$$dense-vector-index-options$$$ * {applies_to}`stack: ga 9.1` Default for float vectors with less than 384 dimensions. * {applies_to}`stack: ga 9.0` Default for float all vectors. This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16`. This can reduce the memory footprint by 4x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). - * `int4_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16` . This can reduce the memory footprint by 8x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). - * `bbq_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically binary quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16` . This can reduce the memory footprint by 32x at the cost of accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). + * `int4_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16`. This can reduce the memory footprint by 8x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). + * `bbq_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically binary quantization for scalable approximate kNN search with `element_type` of `float` or `bfloat16`. This can reduce the memory footprint by 32x at the cost of accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization). {applies_to}`stack: ga 9.1` `bbq_hnsw` is the default index type for float vectors with greater than or equal to 384 dimensions. * `flat` - This utilizes a brute-force search algorithm for exact kNN search. This supports all `element_type` values. From 7270d9070b3f09c70ea4f725b65b10a6b1a33fae Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Mon, 24 Nov 2025 13:27:24 +0000 Subject: [PATCH 07/13] Disallow bfloat16 with semantic_text at the moment --- .../xpack/inference/mapper/SemanticTextFieldMapper.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java index d10cda2e14739..59ad6e0acde09 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapper.java @@ -1394,6 +1394,10 @@ private static void configureDenseVectorMapperBuilder( } } + if (modelSettings.elementType() == DenseVectorFieldMapper.ElementType.BFLOAT16) { + throw new IllegalArgumentException("semantic_text does not support bfloat16"); + } + denseVectorMapperBuilder.dimensions(modelSettings.dimensions()); denseVectorMapperBuilder.elementType(modelSettings.elementType()); // Here is where we persist index_options. If they are specified by the user, we will use those index_options, From a6bffff206bf5a301cee13f3d45955bd4dd8a118 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Mon, 24 Nov 2025 17:19:33 +0000 Subject: [PATCH 08/13] Update semantic text tests --- .../integration/CreateInferenceEndpointIT.java | 2 +- .../integration/SemanticTextIndexVersionIT.java | 5 ++++- .../mapper/SemanticTextFieldMapperTests.java | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/CreateInferenceEndpointIT.java b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/CreateInferenceEndpointIT.java index 27e8d089de03a..005d4b6d791bc 100644 --- a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/CreateInferenceEndpointIT.java +++ b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/CreateInferenceEndpointIT.java @@ -293,7 +293,7 @@ private static Map getRandomServiceSettings() { settings.put(API_KEY, randomIdentifier()); // Always use a dimension that's a multiple of 8 because the BIT element type requires that settings.put(DIMENSIONS, randomIntBetween(1, 32) * 8); - ElementType elementType = randomFrom(ElementType.values()); + ElementType elementType = randomValueOtherThan(ElementType.BFLOAT16, () -> randomFrom(ElementType.values())); settings.put(ELEMENT_TYPE, elementType.toString()); if (elementType == ElementType.BIT) { // The only supported similarity measure for BIT vectors is L2_NORM diff --git a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexVersionIT.java b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexVersionIT.java index caac505bacf9d..549bcb50c5977 100644 --- a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexVersionIT.java +++ b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexVersionIT.java @@ -58,7 +58,10 @@ public class SemanticTextIndexVersionIT extends ESIntegTestCase { @Before public void setup() throws Exception { ModelRegistry modelRegistry = internalCluster().getCurrentMasterNodeInstance(ModelRegistry.class); - DenseVectorFieldMapper.ElementType elementType = randomFrom(DenseVectorFieldMapper.ElementType.values()); + DenseVectorFieldMapper.ElementType elementType = randomValueOtherThan( + DenseVectorFieldMapper.ElementType.BFLOAT16, + () -> randomFrom(DenseVectorFieldMapper.ElementType.values()) + ); // dot product means that we need normalized vectors; it's not worth doing that in this test SimilarityMeasure similarity = randomValueOtherThan( SimilarityMeasure.DOT_PRODUCT, diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapperTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapperTests.java index 3ff591cc85939..e20fce3114a40 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapperTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextFieldMapperTests.java @@ -1593,6 +1593,22 @@ public void testDenseVectorElementType() throws IOException { ) ); assertMapperService.accept(byteMapperService, DenseVectorFieldMapper.ElementType.BYTE); + + var e = expectThrows( + DocumentParsingException.class, + () -> mapperServiceForFieldWithModelSettings( + fieldName, + inferenceId, + new MinimalServiceSettings( + "my-service", + TaskType.TEXT_EMBEDDING, + 1024, + SimilarityMeasure.COSINE, + DenseVectorFieldMapper.ElementType.BFLOAT16 + ) + ) + ); + assertThat(e.getCause(), instanceOf(IllegalArgumentException.class)); } public void testSettingAndUpdatingChunkingSettings() throws IOException { From 47d666e73bc4ca237883f2235f898727fe2a2712 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Tue, 25 Nov 2025 14:58:42 +0000 Subject: [PATCH 09/13] Add an index version --- .../src/main/java/org/elasticsearch/index/IndexVersions.java | 1 + .../xpack/inference/queries/SemanticQueryBuilderTests.java | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/index/IndexVersions.java b/server/src/main/java/org/elasticsearch/index/IndexVersions.java index 134cf076c53bd..ea923573b076a 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexVersions.java +++ b/server/src/main/java/org/elasticsearch/index/IndexVersions.java @@ -197,6 +197,7 @@ private static Version parseUnchecked(String version) { public static final IndexVersion TIME_SERIES_ALL_FIELDS_USE_SKIPPERS = def(9_046_0_00, Version.LUCENE_10_3_1); public static final IndexVersion UPGRADE_TO_LUCENE_10_3_2 = def(9_047_0_00, Version.LUCENE_10_3_2); public static final IndexVersion SECURITY_MIGRATIONS_METADATA_FLATTENED_UPDATE = def(9_048_0_00, Version.LUCENE_10_3_2); + public static final IndexVersion GENERIC_DENSE_VECTOR_FORMAT = def(9_049_0_00, Version.LUCENE_10_3_2); /* * STOP! READ THIS FIRST! No, really, diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilderTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilderTests.java index a475b8a1f4342..9a3e3f8419841 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilderTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilderTests.java @@ -135,7 +135,10 @@ public static void setInferenceResultType() { // These are class variables because they are used when initializing additional mappings, which happens once per test suite run in // AbstractBuilderTestCase#beforeTest as part of service holder creation. inferenceResultType = randomFrom(InferenceResultType.values()); - denseVectorElementType = randomFrom(DenseVectorFieldMapper.ElementType.values()); + denseVectorElementType = randomValueOtherThan( + DenseVectorFieldMapper.ElementType.BFLOAT16, + () -> randomFrom(DenseVectorFieldMapper.ElementType.values()) + ); useSearchInferenceId = randomBoolean(); } From bf465d55437210953423a54333dcf4860c7abb03 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Tue, 25 Nov 2025 15:44:14 +0000 Subject: [PATCH 10/13] Remove feature flag refrences --- .../elasticsearch/xpack/esql/DenseVectorFieldTypeIT.java | 6 +----- .../org/elasticsearch/xpack/esql/plugin/KnnFunctionIT.java | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/DenseVectorFieldTypeIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/DenseVectorFieldTypeIT.java index a5ad9f84ef8f7..dca75aa619f2a 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/DenseVectorFieldTypeIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/DenseVectorFieldTypeIT.java @@ -14,7 +14,6 @@ import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.codec.vectors.BFloat16; -import org.elasticsearch.index.codec.vectors.es93.ES93GenericFlatVectorsFormat; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.script.field.vectors.DenseVector; @@ -72,10 +71,7 @@ private enum VectorSourceOptions { @ParametersFactory public static Iterable parameters() { List params = new ArrayList<>(); - ElementType[] elementTypes = ES93GenericFlatVectorsFormat.GENERIC_VECTOR_FORMAT.isEnabled() - ? ElementType.values() - : new ElementType[] { ElementType.BYTE, ElementType.FLOAT, ElementType.BIT }; - for (ElementType elementType : elementTypes) { + for (ElementType elementType : ElementType.values()) { // Test all similarities for (DenseVectorFieldMapper.VectorSimilarity similarity : DenseVectorFieldMapper.VectorSimilarity.values()) { if (elementType == ElementType.BIT && similarity != DenseVectorFieldMapper.VectorSimilarity.L2_NORM) { diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KnnFunctionIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KnnFunctionIT.java index a2be1f51b36fa..96ef347d70315 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KnnFunctionIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KnnFunctionIT.java @@ -15,7 +15,6 @@ import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.IndexSettings; -import org.elasticsearch.index.codec.vectors.es93.ES93GenericFlatVectorsFormat; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentFactory; @@ -58,9 +57,7 @@ public static Iterable parameters() throws Exception { List params = new ArrayList<>(); for (String indexType : ALL_DENSE_VECTOR_INDEX_TYPES) { params.add(new Object[] { DenseVectorFieldMapper.ElementType.FLOAT, indexType }); - if (ES93GenericFlatVectorsFormat.GENERIC_VECTOR_FORMAT.isEnabled()) { - params.add(new Object[] { DenseVectorFieldMapper.ElementType.BFLOAT16, indexType }); - } + params.add(new Object[] { DenseVectorFieldMapper.ElementType.BFLOAT16, indexType }); } for (String indexType : NON_QUANTIZED_DENSE_VECTOR_INDEX_TYPES) { params.add(new Object[] { DenseVectorFieldMapper.ElementType.BYTE, indexType }); From 056bd28f5a04129686090943ef815de17aaffb5e Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Tue, 25 Nov 2025 16:20:13 +0000 Subject: [PATCH 11/13] Another one --- .../inference/integration/SemanticTextIndexOptionsIT.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexOptionsIT.java b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexOptionsIT.java index 26a18878948ef..eb187961225b9 100644 --- a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexOptionsIT.java +++ b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/SemanticTextIndexOptionsIT.java @@ -15,7 +15,6 @@ import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.core.Nullable; import org.elasticsearch.core.TimeValue; -import org.elasticsearch.index.codec.vectors.es93.ES93GenericFlatVectorsFormat; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; import org.elasticsearch.index.mapper.vectors.IndexOptions; import org.elasticsearch.inference.TaskType; @@ -121,7 +120,7 @@ public void testValidateIndexOptionsWithBasicLicense() throws Exception { randomIntBetween(1, 100), randomIntBetween(1, 10_000), null, - ES93GenericFlatVectorsFormat.GENERIC_VECTOR_FORMAT.isEnabled() && randomBoolean(), + randomBoolean(), null ); assertAcked( From 171d1d34bac702c4dd922fc3033b8f3d8625bbee Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Tue, 25 Nov 2025 16:21:36 +0000 Subject: [PATCH 12/13] Update docs/changelog/138492.yaml --- docs/changelog/138492.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/changelog/138492.yaml b/docs/changelog/138492.yaml index e163e5c15cb35..90796a9ba57a1 100644 --- a/docs/changelog/138492.yaml +++ b/docs/changelog/138492.yaml @@ -1,11 +1,11 @@ pr: 138492 summary: Enable bfloat16 and on-disk rescoring for dense vectors area: Vector Search -type: feature +type: "docs, feature" issues: [] highlight: - notable: true - title: New dense_vector options for storing bfloat16 vectors and utilising on-disk rescoring + title: New dense_vector options for storing bfloat16 vectors and utilising on-disk + rescoring body: |- New options have been added to the `dense_vector` field type. @@ -58,3 +58,4 @@ highlight: } } ---------------------------- + notable: true From 678463e43f641f7754a3ca29a51643da694a51b2 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Tue, 25 Nov 2025 16:33:55 +0000 Subject: [PATCH 13/13] Fix changelog --- docs/changelog/138492.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog/138492.yaml b/docs/changelog/138492.yaml index 90796a9ba57a1..eac953362f759 100644 --- a/docs/changelog/138492.yaml +++ b/docs/changelog/138492.yaml @@ -1,7 +1,7 @@ pr: 138492 summary: Enable bfloat16 and on-disk rescoring for dense vectors area: Vector Search -type: "docs, feature" +type: feature issues: [] highlight: title: New dense_vector options for storing bfloat16 vectors and utilising on-disk