From df30d6366b089e3794b0390a8f83ede375865ecd Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Thu, 4 Sep 2025 13:15:23 +0100 Subject: [PATCH 1/4] Separate out Element and ElementType --- .../vectors/DenseVectorFieldMapper.java | 156 ++++++------------ 1 file changed, 53 insertions(+), 103 deletions(-) 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 67cf720dc78b5..2b6e07a7c7749 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 @@ -454,54 +454,36 @@ public DenseVectorFieldMapper build(MapperBuilderContext context) { } public enum ElementType { - - BYTE(new ElementTypeByteBehavior()), - FLOAT(new ElementTypeFloatBehavior()), - BIT(new ElementTypeBitBehavior()); - - private final ElementTypeBehavior behavior; - - ElementType(ElementTypeBehavior behavior) { - this.behavior = behavior; - } + BYTE, FLOAT, BIT; @Override public String toString() { return super.toString().toLowerCase(Locale.ROOT); } + } - public void writeValue(ByteBuffer byteBuffer, float value) { - behavior.writeValue(byteBuffer, value); - } - - public void readAndWriteValue(ByteBuffer byteBuffer, XContentBuilder b) throws IOException { - behavior.readAndWriteValue(byteBuffer, b); - } - - IndexFieldData.Builder fielddataBuilder(DenseVectorFieldType denseVectorFieldType, FieldDataContext fieldDataContext) { - return behavior.fielddataBuilder(denseVectorFieldType, fieldDataContext); - } - - void parseKnnVectorAndIndex(DocumentParserContext context, DenseVectorFieldMapper fieldMapper) throws IOException { - behavior.parseKnnVectorAndIndex(context, fieldMapper); - } + public static final Element BYTE_ELEMENT = new ByteElement(); + public static final Element FLOAT_ELEMENT = new FloatElement(); + public static final Element BIT_ELEMENT = new BitElement(); - public VectorData parseKnnVector( - DocumentParserContext context, - int dims, - IntBooleanConsumer dimChecker, - VectorSimilarity similarity - ) throws IOException { - return behavior.parseKnnVector(context, dims, dimChecker, similarity); - } + public static final Map namesToElementType = Map.of( + ElementType.BYTE.toString(), + ElementType.BYTE, + ElementType.FLOAT.toString(), + ElementType.FLOAT, + ElementType.BIT.toString(), + ElementType.BIT + ); - public int getNumBytes(int dimensions) { - return behavior.getNumBytes(dimensions); - } + private static final Map elements = Map.of( + ElementType.BYTE, + BYTE_ELEMENT, + ElementType.FLOAT, + FLOAT_ELEMENT, + ElementType.BIT, + BIT_ELEMENT); - public ByteBuffer createByteBuffer(IndexVersion indexVersion, int numBytes) { - return behavior.createByteBuffer(indexVersion, numBytes); - } + public static abstract class Element { /** * Checks the input {@code vector} is one of the {@code possibleTypes}, @@ -513,7 +495,7 @@ public static ElementType checkValidVector(float[] vector, ElementType... possib // assume the types are in order of specificity StringBuilder[] errors = new StringBuilder[possibleTypes.length]; for (int i = 0; i < possibleTypes.length; i++) { - StringBuilder error = possibleTypes[i].behavior.checkVectorErrors(vector); + StringBuilder error = elements.get(possibleTypes[i]).checkVectorErrors(vector); if (error == null) { // this one works - use it return possibleTypes[i]; @@ -530,36 +512,9 @@ public static ElementType checkValidVector(float[] vector, ElementType... possib } message.append("Vector is not a ").append(possibleTypes[i]).append(" vector: ").append(errors[i]); } - throw new IllegalArgumentException(ElementTypeFloatBehavior.appendErrorElements(message, vector).toString()); - } - - public void checkVectorBounds(float[] vector) { - behavior.checkVectorBounds(vector); - } - - void checkVectorMagnitude(VectorSimilarity similarity, UnaryOperator errorElementsAppender, float squaredMagnitude) { - behavior.checkVectorMagnitude(similarity, errorElementsAppender, squaredMagnitude); + throw new IllegalArgumentException(FloatElement.appendErrorElements(message, vector).toString()); } - public void checkDimensions(Integer dvDims, int qvDims) { - behavior.checkDimensions(dvDims, qvDims); - } - - public int parseDimensionCount(DocumentParserContext context) throws IOException { - return behavior.parseDimensionCount(context); - } - - public double computeSquaredMagnitude(VectorData vectorData) { - return behavior.computeSquaredMagnitude(vectorData); - } - - public static ElementType fromString(String name) { - return valueOf(name.trim().toUpperCase(Locale.ROOT)); - } - } - - private abstract static class ElementTypeBehavior { - abstract ElementType elementType(); abstract void writeValue(ByteBuffer byteBuffer, float value); @@ -584,7 +539,7 @@ abstract VectorData parseKnnVector( void checkVectorBounds(float[] vector) { StringBuilder errors = checkVectorErrors(vector); if (errors != null) { - throw new IllegalArgumentException(ElementTypeFloatBehavior.appendErrorElements(errors, vector).toString()); + throw new IllegalArgumentException(FloatElement.appendErrorElements(errors, vector).toString()); } } @@ -653,7 +608,7 @@ StringBuilder checkNanAndInfinite(float[] vector) { public abstract double computeSquaredMagnitude(VectorData vectorData); } - private static class ElementTypeByteBehavior extends ElementTypeBehavior { + private static class ByteElement extends Element { @Override ElementType elementType() { @@ -905,7 +860,7 @@ static UnaryOperator errorElementsAppender(byte[] vector) { } } - private static class ElementTypeFloatBehavior extends ElementTypeBehavior { + private static class FloatElement extends Element { @Override ElementType elementType() { @@ -1090,7 +1045,7 @@ static UnaryOperator errorElementsAppender(float[] vector) { } } - private static class ElementTypeBitBehavior extends ElementTypeByteBehavior { + private static class BitElement extends ByteElement { @Override ElementType elementType() { @@ -1152,15 +1107,6 @@ public void checkDimensions(Integer dvDims, int qvDims) { } } - public static final Map namesToElementType = Map.of( - ElementType.BYTE.toString(), - ElementType.BYTE, - ElementType.FLOAT.toString(), - ElementType.FLOAT, - ElementType.BIT.toString(), - ElementType.BIT - ); - public enum VectorSimilarity { L2_NORM { @Override @@ -2275,6 +2221,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws public static final class DenseVectorFieldType extends SimpleMappedFieldType { private final ElementType elementType; + private final Element element; private final Integer dims; private final boolean indexed; private final VectorSimilarity similarity; @@ -2301,6 +2248,9 @@ public DenseVectorFieldType( this.indexVersionCreated = indexVersionCreated; this.indexOptions = indexOptions; this.isSyntheticSource = isSyntheticSource; + + this.element = elements.get(elementType); + assert this.element != null; } @Override @@ -2338,7 +2288,7 @@ public boolean isVectorEmbedding() { @Override public IndexFieldData.Builder fielddataBuilder(FieldDataContext fieldDataContext) { - return elementType.fielddataBuilder(this, fieldDataContext); + return element.fielddataBuilder(this, fieldDataContext); } @Override @@ -2373,25 +2323,25 @@ public boolean isNormalized() { } private Query createExactKnnBitQuery(byte[] queryVector) { - elementType.checkDimensions(dims, queryVector.length); + elements.get(elementType).checkDimensions(dims, queryVector.length); return new DenseVectorQuery.Bytes(queryVector, name()); } private Query createExactKnnByteQuery(byte[] queryVector) { - elementType.checkDimensions(dims, queryVector.length); + elements.get(elementType).checkDimensions(dims, queryVector.length); if (similarity == VectorSimilarity.DOT_PRODUCT || similarity == VectorSimilarity.COSINE) { float squaredMagnitude = VectorUtil.dotProduct(queryVector, queryVector); - elementType.checkVectorMagnitude(similarity, ElementTypeByteBehavior.errorElementsAppender(queryVector), squaredMagnitude); + elements.get(elementType).checkVectorMagnitude(similarity, ByteElement.errorElementsAppender(queryVector), squaredMagnitude); } return new DenseVectorQuery.Bytes(queryVector, name()); } private Query createExactKnnFloatQuery(float[] queryVector) { - elementType.checkDimensions(dims, queryVector.length); - elementType.checkVectorBounds(queryVector); + element.checkDimensions(dims, queryVector.length); + element.checkVectorBounds(queryVector); if (similarity == VectorSimilarity.DOT_PRODUCT || similarity == VectorSimilarity.COSINE) { float squaredMagnitude = VectorUtil.dotProduct(queryVector, queryVector); - elementType.checkVectorMagnitude(similarity, ElementTypeFloatBehavior.errorElementsAppender(queryVector), squaredMagnitude); + element.checkVectorMagnitude(similarity, FloatElement.errorElementsAppender(queryVector), squaredMagnitude); if (isNormalized() && isNotUnitVector(squaredMagnitude)) { float length = (float) Math.sqrt(squaredMagnitude); queryVector = Arrays.copyOf(queryVector, queryVector.length); @@ -2476,7 +2426,7 @@ private Query createKnnBitQuery( KnnSearchStrategy searchStrategy, boolean hnswEarlyTermination ) { - elementType.checkDimensions(dims, queryVector.length); + element.checkDimensions(dims, queryVector.length); Query knnQuery; if (indexOptions != null && indexOptions.isFlat()) { var exactKnnQuery = parentFilter != null @@ -2515,11 +2465,11 @@ private Query createKnnByteQuery( KnnSearchStrategy searchStrategy, boolean hnswEarlyTermination ) { - elementType.checkDimensions(dims, queryVector.length); + element.checkDimensions(dims, queryVector.length); if (similarity == VectorSimilarity.DOT_PRODUCT || similarity == VectorSimilarity.COSINE) { float squaredMagnitude = VectorUtil.dotProduct(queryVector, queryVector); - elementType.checkVectorMagnitude(similarity, ElementTypeByteBehavior.errorElementsAppender(queryVector), squaredMagnitude); + element.checkVectorMagnitude(similarity, ByteElement.errorElementsAppender(queryVector), squaredMagnitude); } Query knnQuery; if (indexOptions != null && indexOptions.isFlat()) { @@ -2577,11 +2527,11 @@ private Query createKnnFloatQuery( KnnSearchStrategy knnSearchStrategy, boolean hnswEarlyTermination ) { - elementType.checkDimensions(dims, queryVector.length); - elementType.checkVectorBounds(queryVector); + element.checkDimensions(dims, queryVector.length); + element.checkVectorBounds(queryVector); if (similarity == VectorSimilarity.DOT_PRODUCT || similarity == VectorSimilarity.COSINE) { float squaredMagnitude = VectorUtil.dotProduct(queryVector, queryVector); - elementType.checkVectorMagnitude(similarity, ElementTypeFloatBehavior.errorElementsAppender(queryVector), squaredMagnitude); + element.checkVectorMagnitude(similarity, FloatElement.errorElementsAppender(queryVector), squaredMagnitude); if (isNormalized() && isNotUnitVector(squaredMagnitude)) { float length = (float) Math.sqrt(squaredMagnitude); queryVector = Arrays.copyOf(queryVector, queryVector.length); @@ -2768,7 +2718,7 @@ public void parse(DocumentParserContext context) throws IOException { return; } if (fieldType().dims == null) { - int dims = fieldType().elementType.parseDimensionCount(context); + int dims = fieldType().element.parseDimensionCount(context); DenseVectorFieldMapper.Builder builder = (Builder) getMergeBuilder(); builder.dimensions(dims); Mapper update = builder.build(context.createDynamicMapperBuilderContext()); @@ -2783,20 +2733,20 @@ public void parse(DocumentParserContext context) throws IOException { } private void parseKnnVectorAndIndex(DocumentParserContext context) throws IOException { - fieldType().elementType.parseKnnVectorAndIndex(context, this); + fieldType().element.parseKnnVectorAndIndex(context, this); } private void parseBinaryDocValuesVectorAndIndex(DocumentParserContext context) throws IOException { // encode array of floats as array of integers and store into buf // this code is here and not in the VectorEncoderDecoder so not to create extra arrays int dims = fieldType().dims; - ElementType elementType = fieldType().elementType; + Element element = fieldType().element; int numBytes = indexCreatedVersion.onOrAfter(MAGNITUDE_STORED_INDEX_VERSION) - ? elementType.getNumBytes(dims) + MAGNITUDE_BYTES - : elementType.getNumBytes(dims); + ? element.getNumBytes(dims) + MAGNITUDE_BYTES + : element.getNumBytes(dims); - ByteBuffer byteBuffer = elementType.createByteBuffer(indexCreatedVersion, numBytes); - VectorData vectorData = elementType.parseKnnVector(context, dims, (i, b) -> { + ByteBuffer byteBuffer = element.createByteBuffer(indexCreatedVersion, numBytes); + VectorData vectorData = element.parseKnnVector(context, dims, (i, b) -> { if (b) { checkDimensionMatches(i, context); } else { @@ -2806,7 +2756,7 @@ private void parseBinaryDocValuesVectorAndIndex(DocumentParserContext context) t vectorData.addToBuffer(byteBuffer); if (indexCreatedVersion.onOrAfter(MAGNITUDE_STORED_INDEX_VERSION)) { // encode vector magnitude at the end - double dotProduct = elementType.computeSquaredMagnitude(vectorData); + double dotProduct = element.computeSquaredMagnitude(vectorData); float vectorMagnitude = (float) Math.sqrt(dotProduct); byteBuffer.putFloat(vectorMagnitude); } @@ -3099,7 +3049,7 @@ public void write(XContentBuilder b) throws IOException { } int dims = fieldType().elementType == ElementType.BIT ? fieldType().dims / Byte.SIZE : fieldType().dims; for (int dim = 0; dim < dims; dim++) { - fieldType().elementType.readAndWriteValue(byteBuffer, b); + fieldType().element.readAndWriteValue(byteBuffer, b); } b.endArray(); } From ccd0a2360317770d44434207ab0e4a58fada2b11 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Thu, 4 Sep 2025 14:30:55 +0100 Subject: [PATCH 2/4] Propagate changes --- .../vectors/DenseVectorFieldMapper.java | 94 ++++++++++--------- .../script/VectorScoreScriptUtils.java | 7 +- .../vectors/DenseVectorDocValuesField.java | 5 + .../vectors/RankVectorsDocValuesField.java | 9 +- .../search/vectors/VectorData.java | 2 +- ...BinaryDenseVectorScriptDocValuesTests.java | 8 +- .../vectors/VectorEncoderDecoderTests.java | 2 +- .../mapper/RankVectorsFieldMapper.java | 40 ++++---- .../script/RankVectorsScoreScriptUtils.java | 6 +- .../mapper/RankVectorsFieldMapperTests.java | 3 +- .../RankVectorsScriptDocValuesTests.java | 6 +- 11 files changed, 103 insertions(+), 79 deletions(-) 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 2b6e07a7c7749..9712543cfb238 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 @@ -245,7 +245,7 @@ public static class Builder extends FieldMapper.Builder { throw new MapperParsingException("invalid element_type [" + o + "]; available types are " + namesToElementType.keySet()); } return elementType; - }, m -> toType(m).fieldType().elementType, XContentBuilder::field, Objects::toString); + }, m -> toType(m).fieldType().element.elementType(), XContentBuilder::field, Objects::toString); private final Parameter dims; private final Parameter similarity; @@ -454,7 +454,13 @@ public DenseVectorFieldMapper build(MapperBuilderContext context) { } public enum ElementType { - BYTE, FLOAT, BIT; + BYTE, + FLOAT, + BIT; + + public static ElementType fromString(String name) { + return valueOf(name.toUpperCase(Locale.ROOT)); + } @Override public String toString() { @@ -475,15 +481,15 @@ public String toString() { ElementType.BIT ); - private static final Map elements = Map.of( - ElementType.BYTE, - BYTE_ELEMENT, - ElementType.FLOAT, - FLOAT_ELEMENT, - ElementType.BIT, - BIT_ELEMENT); + public abstract static class Element { - public static abstract class Element { + public static Element getElement(ElementType elementType) { + return switch (elementType) { + case FLOAT -> FLOAT_ELEMENT; + case BYTE -> BYTE_ELEMENT; + case BIT -> BIT_ELEMENT; + }; + } /** * Checks the input {@code vector} is one of the {@code possibleTypes}, @@ -495,7 +501,7 @@ public static ElementType checkValidVector(float[] vector, ElementType... possib // assume the types are in order of specificity StringBuilder[] errors = new StringBuilder[possibleTypes.length]; for (int i = 0; i < possibleTypes.length; i++) { - StringBuilder error = elements.get(possibleTypes[i]).checkVectorErrors(vector); + StringBuilder error = getElement(possibleTypes[i]).checkVectorErrors(vector); if (error == null) { // this one works - use it return possibleTypes[i]; @@ -515,28 +521,28 @@ public static ElementType checkValidVector(float[] vector, ElementType... possib throw new IllegalArgumentException(FloatElement.appendErrorElements(message, vector).toString()); } - abstract ElementType elementType(); + public abstract ElementType elementType(); - abstract void writeValue(ByteBuffer byteBuffer, float value); + public abstract void writeValue(ByteBuffer byteBuffer, float value); - abstract void readAndWriteValue(ByteBuffer byteBuffer, XContentBuilder b) throws IOException; + public abstract void readAndWriteValue(ByteBuffer byteBuffer, XContentBuilder b) throws IOException; abstract IndexFieldData.Builder fielddataBuilder(DenseVectorFieldType denseVectorFieldType, FieldDataContext fieldDataContext); abstract void parseKnnVectorAndIndex(DocumentParserContext context, DenseVectorFieldMapper fieldMapper) throws IOException; - abstract VectorData parseKnnVector( + public abstract VectorData parseKnnVector( DocumentParserContext context, int dims, IntBooleanConsumer dimChecker, VectorSimilarity similarity ) throws IOException; - abstract int getNumBytes(int dimensions); + public abstract int getNumBytes(int dimensions); - abstract ByteBuffer createByteBuffer(IndexVersion indexVersion, int numBytes); + public abstract ByteBuffer createByteBuffer(IndexVersion indexVersion, int numBytes); - void checkVectorBounds(float[] vector) { + public void checkVectorBounds(float[] vector) { StringBuilder errors = checkVectorErrors(vector); if (errors != null) { throw new IllegalArgumentException(FloatElement.appendErrorElements(errors, vector).toString()); @@ -553,7 +559,9 @@ abstract void checkVectorMagnitude( float squaredMagnitude ); - void checkDimensions(Integer dvDims, int qvDims) { + public abstract double computeSquaredMagnitude(VectorData vectorData); + + public void checkDimensions(Integer dvDims, int qvDims) { if (dvDims != null && dvDims != qvDims) { throw new IllegalArgumentException( "The query vector has a different number of dimensions [" + qvDims + "] than the document vectors [" + dvDims + "]." @@ -561,7 +569,7 @@ void checkDimensions(Integer dvDims, int qvDims) { } } - int parseDimensionCount(DocumentParserContext context) throws IOException { + public int parseDimensionCount(DocumentParserContext context) throws IOException { int index = 0; for (Token token = context.parser().nextToken(); token != Token.END_ARRAY; token = context.parser().nextToken()) { index++; @@ -604,14 +612,12 @@ StringBuilder checkNanAndInfinite(float[] vector) { return errorBuilder; } - - public abstract double computeSquaredMagnitude(VectorData vectorData); } private static class ByteElement extends Element { @Override - ElementType elementType() { + public ElementType elementType() { return ElementType.BYTE; } @@ -863,7 +869,7 @@ static UnaryOperator errorElementsAppender(byte[] vector) { private static class FloatElement extends Element { @Override - ElementType elementType() { + public ElementType elementType() { return ElementType.FLOAT; } @@ -1048,7 +1054,7 @@ static UnaryOperator errorElementsAppender(float[] vector) { private static class BitElement extends ByteElement { @Override - ElementType elementType() { + public ElementType elementType() { return ElementType.BIT; } @@ -2220,7 +2226,6 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws ); public static final class DenseVectorFieldType extends SimpleMappedFieldType { - private final ElementType elementType; private final Element element; private final Integer dims; private final boolean indexed; @@ -2241,16 +2246,13 @@ public DenseVectorFieldType( boolean isSyntheticSource ) { super(name, indexed, false, indexed == false, TextSearchInfo.NONE, meta); - this.elementType = elementType; + this.element = Element.getElement(elementType); this.dims = dims; this.indexed = indexed; this.similarity = similarity; this.indexVersionCreated = indexVersionCreated; this.indexOptions = indexOptions; this.isSyntheticSource = isSyntheticSource; - - this.element = elements.get(elementType); - assert this.element != null; } @Override @@ -2307,13 +2309,17 @@ public Query createExactKnnQuery(VectorData queryVector, Float vectorSimilarity) "to perform knn search on field [" + name() + "], its mapping must have [index] set to [true]" ); } - Query knnQuery = switch (elementType) { + Query knnQuery = switch (element.elementType()) { case BYTE -> createExactKnnByteQuery(queryVector.asByteVector()); case FLOAT -> createExactKnnFloatQuery(queryVector.asFloatVector()); case BIT -> createExactKnnBitQuery(queryVector.asByteVector()); }; if (vectorSimilarity != null) { - knnQuery = new VectorSimilarityQuery(knnQuery, vectorSimilarity, similarity.score(vectorSimilarity, elementType, dims)); + knnQuery = new VectorSimilarityQuery( + knnQuery, + vectorSimilarity, + similarity.score(vectorSimilarity, element.elementType(), dims) + ); } return knnQuery; } @@ -2323,15 +2329,15 @@ public boolean isNormalized() { } private Query createExactKnnBitQuery(byte[] queryVector) { - elements.get(elementType).checkDimensions(dims, queryVector.length); + element.checkDimensions(dims, queryVector.length); return new DenseVectorQuery.Bytes(queryVector, name()); } private Query createExactKnnByteQuery(byte[] queryVector) { - elements.get(elementType).checkDimensions(dims, queryVector.length); + element.checkDimensions(dims, queryVector.length); if (similarity == VectorSimilarity.DOT_PRODUCT || similarity == VectorSimilarity.COSINE) { float squaredMagnitude = VectorUtil.dotProduct(queryVector, queryVector); - elements.get(elementType).checkVectorMagnitude(similarity, ByteElement.errorElementsAppender(queryVector), squaredMagnitude); + element.checkVectorMagnitude(similarity, ByteElement.errorElementsAppender(queryVector), squaredMagnitude); } return new DenseVectorQuery.Bytes(queryVector, name()); } @@ -2449,7 +2455,7 @@ private Query createKnnBitQuery( knnQuery = new VectorSimilarityQuery( knnQuery, similarityThreshold, - similarity.score(similarityThreshold, elementType, dims) + similarity.score(similarityThreshold, element.elementType(), dims) ); } return knnQuery; @@ -2493,7 +2499,7 @@ private Query createKnnByteQuery( knnQuery = new VectorSimilarityQuery( knnQuery, similarityThreshold, - similarity.score(similarityThreshold, elementType, dims) + similarity.score(similarityThreshold, element.elementType(), dims) ); } return knnQuery; @@ -2609,7 +2615,7 @@ private Query createKnnFloatQuery( knnQuery = new VectorSimilarityQuery( knnQuery, similarityThreshold, - similarity.score(similarityThreshold, elementType, dims) + similarity.score(similarityThreshold, element.elementType(), dims) ); } return knnQuery; @@ -2624,7 +2630,7 @@ int getVectorDimensions() { } public ElementType getElementType() { - return elementType; + return element.elementType(); } public DenseVectorIndexOptions getIndexOptions() { @@ -2633,7 +2639,7 @@ public DenseVectorIndexOptions getIndexOptions() { @Override public BlockLoader blockLoader(MappedFieldType.BlockLoaderContext blContext) { - if (elementType == ElementType.BIT) { + if (element.elementType() == ElementType.BIT) { // Just float and byte dense vector support for now return null; } @@ -2648,7 +2654,7 @@ public BlockLoader blockLoader(MappedFieldType.BlockLoaderContext blContext) { } if (hasDocValues() && (blContext.fieldExtractPreference() != FieldExtractPreference.STORED || isSyntheticSource)) { - return new BlockDocValuesReader.DenseVectorFromBinaryBlockLoader(name(), dims, indexVersionCreated, elementType); + return new BlockDocValuesReader.DenseVectorFromBinaryBlockLoader(name(), dims, indexVersionCreated, element.elementType()); } BlockSourceReader.LeafIteratorLookup lookup = BlockSourceReader.lookupMatchingAll(); @@ -2838,9 +2844,9 @@ private static DenseVectorIndexOptions parseIndexOptions(String fieldName, Objec public KnnVectorsFormat getKnnVectorsFormatForField(KnnVectorsFormat defaultFormat) { final KnnVectorsFormat format; if (indexOptions == null) { - format = fieldType().elementType == ElementType.BIT ? new ES815HnswBitVectorsFormat() : defaultFormat; + format = fieldType().element.elementType() == ElementType.BIT ? new ES815HnswBitVectorsFormat() : defaultFormat; } else { - format = indexOptions.getVectorsFormat(fieldType().elementType); + format = indexOptions.getVectorsFormat(fieldType().element.elementType()); } // It's legal to reuse the same format name as this is the same on-disk format. return new KnnVectorsFormat(format.getName()) { @@ -3047,7 +3053,7 @@ public void write(XContentBuilder b) throws IOException { if (indexCreatedVersion.onOrAfter(LITTLE_ENDIAN_FLOAT_STORED_INDEX_VERSION)) { byteBuffer.order(ByteOrder.LITTLE_ENDIAN); } - int dims = fieldType().elementType == ElementType.BIT ? fieldType().dims / Byte.SIZE : fieldType().dims; + int dims = fieldType().element.elementType() == ElementType.BIT ? fieldType().dims / Byte.SIZE : fieldType().dims; for (int dim = 0; dim < dims; dim++) { fieldType().element.readAndWriteValue(byteBuffer, b); } diff --git a/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java b/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java index d319c8d8b40aa..13be089753fb7 100644 --- a/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java +++ b/server/src/main/java/org/elasticsearch/script/VectorScoreScriptUtils.java @@ -11,6 +11,7 @@ import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.Element; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.script.field.vectors.DenseVector; import org.elasticsearch.script.field.vectors.DenseVectorDocValuesField; @@ -66,7 +67,7 @@ public ByteDenseVectorFunction( ElementType... allowedTypes ) { super(scoreScript, field); - field.getElementType().checkDimensions(field.get().getDims(), queryVector.size()); + field.getElement().checkDimensions(field.get().getDims(), queryVector.size()); float[] floatValues = new float[queryVector.size()]; double queryMagnitude = 0; for (int i = 0; i < queryVector.size(); i++) { @@ -76,7 +77,7 @@ public ByteDenseVectorFunction( } queryMagnitude = Math.sqrt(queryMagnitude); - switch (ElementType.checkValidVector(floatValues, allowedTypes)) { + switch (Element.checkValidVector(floatValues, allowedTypes)) { case FLOAT: byteQueryVector = null; floatQueryVector = floatValues; @@ -149,7 +150,7 @@ public FloatDenseVectorFunction( queryMagnitude += value * value; } queryMagnitude = Math.sqrt(queryMagnitude); - field.getElementType().checkVectorBounds(this.queryVector); + field.getElement().checkVectorBounds(this.queryVector); if (normalizeQuery) { for (int dim = 0; dim < this.queryVector.length; dim++) { diff --git a/server/src/main/java/org/elasticsearch/script/field/vectors/DenseVectorDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/vectors/DenseVectorDocValuesField.java index 1fbee2b972e30..088538af2de7f 100644 --- a/server/src/main/java/org/elasticsearch/script/field/vectors/DenseVectorDocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/vectors/DenseVectorDocValuesField.java @@ -16,6 +16,7 @@ import java.util.Iterator; +import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.Element; import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; public abstract class DenseVectorDocValuesField extends AbstractScriptFieldFactory @@ -40,6 +41,10 @@ public ElementType getElementType() { return elementType; } + public Element getElement() { + return Element.getElement(elementType); + } + @Override public int size() { return isEmpty() ? 0 : 1; diff --git a/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java index 2362561ea88c5..c9b33d735c065 100644 --- a/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java @@ -9,6 +9,9 @@ package org.elasticsearch.script.field.vectors; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.Element; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.index.mapper.vectors.RankVectorsScriptDocValues; import org.elasticsearch.script.field.AbstractScriptFieldFactory; import org.elasticsearch.script.field.DocValuesScriptFieldFactory; @@ -16,8 +19,6 @@ import java.util.Iterator; -import static org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; - public abstract class RankVectorsDocValuesField extends AbstractScriptFieldFactory implements Field, @@ -40,6 +41,10 @@ public ElementType getElementType() { return elementType; } + public Element getElement() { + return DenseVectorFieldMapper.Element.getElement(elementType); + } + /** * Get the DenseVector for a document if one exists, DenseVector.EMPTY otherwise */ diff --git a/server/src/main/java/org/elasticsearch/search/vectors/VectorData.java b/server/src/main/java/org/elasticsearch/search/vectors/VectorData.java index aaddd3499556b..cc35ddebc8205 100644 --- a/server/src/main/java/org/elasticsearch/search/vectors/VectorData.java +++ b/server/src/main/java/org/elasticsearch/search/vectors/VectorData.java @@ -56,7 +56,7 @@ public byte[] asByteVector() { if (byteVector != null) { return byteVector; } - DenseVectorFieldMapper.ElementType.BYTE.checkVectorBounds(floatVector); + DenseVectorFieldMapper.BYTE_ELEMENT.checkVectorBounds(floatVector); byte[] vec = new byte[floatVector.length]; for (int i = 0; i < floatVector.length; i++) { vec[i] = (byte) floatVector[i]; diff --git a/server/src/test/java/org/elasticsearch/index/mapper/vectors/BinaryDenseVectorScriptDocValuesTests.java b/server/src/test/java/org/elasticsearch/index/mapper/vectors/BinaryDenseVectorScriptDocValuesTests.java index a4a4cc77bab8a..e9eac173e2198 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/vectors/BinaryDenseVectorScriptDocValuesTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/vectors/BinaryDenseVectorScriptDocValuesTests.java @@ -12,6 +12,7 @@ import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.util.BytesRef; import org.elasticsearch.index.IndexVersion; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.Element; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.script.field.vectors.BinaryDenseVectorDocValuesField; import org.elasticsearch.script.field.vectors.ByteBinaryDenseVectorDocValuesField; @@ -240,11 +241,12 @@ public static BytesRef mockEncodeDenseVector(float[] values, ElementType element if (elementType == ElementType.BIT) { dims *= Byte.SIZE; } + Element element = Element.getElement(elementType); int numBytes = indexVersion.onOrAfter(DenseVectorFieldMapper.MAGNITUDE_STORED_INDEX_VERSION) - ? elementType.getNumBytes(dims) + DenseVectorFieldMapper.MAGNITUDE_BYTES - : elementType.getNumBytes(dims); + ? element.getNumBytes(dims) + DenseVectorFieldMapper.MAGNITUDE_BYTES + : element.getNumBytes(dims); double dotProduct = 0f; - ByteBuffer byteBuffer = elementType.createByteBuffer(indexVersion, numBytes); + ByteBuffer byteBuffer = element.createByteBuffer(indexVersion, numBytes); for (float value : values) { if (elementType == ElementType.FLOAT) { byteBuffer.putFloat(value); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/vectors/VectorEncoderDecoderTests.java b/server/src/test/java/org/elasticsearch/index/mapper/vectors/VectorEncoderDecoderTests.java index 2e9aa34317ec9..60880a45373af 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/vectors/VectorEncoderDecoderTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/vectors/VectorEncoderDecoderTests.java @@ -34,7 +34,7 @@ public void testVectorDecodingWithOffset() { ), DenseVectorFieldMapper.LITTLE_ENDIAN_FLOAT_STORED_INDEX_VERSION )) { - ByteBuffer byteBuffer = DenseVectorFieldMapper.ElementType.FLOAT.createByteBuffer(version, 20); + ByteBuffer byteBuffer = DenseVectorFieldMapper.FLOAT_ELEMENT.createByteBuffer(version, 20); double magnitude = 0.0; for (float f : inputFloats) { byteBuffer.putFloat(f); diff --git a/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapper.java b/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapper.java index e2f314abc553f..eeafdd6e4eba0 100644 --- a/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapper.java +++ b/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapper.java @@ -29,6 +29,8 @@ import org.elasticsearch.index.mapper.TextSearchInfo; import org.elasticsearch.index.mapper.ValueFetcher; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.Element; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.index.mapper.vectors.SyntheticVectorsPatchFieldLoader; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.license.LicenseUtils; @@ -77,7 +79,7 @@ public static class Builder extends FieldMapper.Builder { } return elementType; }, - m -> toType(m).fieldType().elementType, + m -> toType(m).fieldType().element.elementType(), XContentBuilder::field, Objects::toString ); @@ -160,19 +162,19 @@ public RankVectorsFieldMapper build(MapperBuilderContext context) { } public static final class RankVectorsFieldType extends SimpleMappedFieldType { - private final DenseVectorFieldMapper.ElementType elementType; + private final Element element; private final Integer dims; private final XPackLicenseState licenseState; public RankVectorsFieldType( String name, - DenseVectorFieldMapper.ElementType elementType, + ElementType elementType, Integer dims, XPackLicenseState licenseState, Map meta ) { super(name, false, false, true, TextSearchInfo.NONE, meta); - this.elementType = elementType; + this.element = Element.getElement(elementType); this.dims = dims; this.licenseState = licenseState; } @@ -228,7 +230,7 @@ public IndexFieldData.Builder fielddataBuilder(FieldDataContext fieldDataContext if (RANK_VECTORS_FEATURE.check(licenseState) == false) { throw LicenseUtils.newComplianceException("Rank Vectors"); } - return new RankVectorsIndexFieldData.Builder(name(), CoreValuesSourceType.KEYWORD, dims, elementType); + return new RankVectorsIndexFieldData.Builder(name(), CoreValuesSourceType.KEYWORD, dims, element.elementType()); } @Override @@ -246,7 +248,7 @@ int getVectorDimensions() { } DenseVectorFieldMapper.ElementType getElementType() { - return elementType; + return element.elementType(); } } @@ -303,7 +305,7 @@ public void parse(DocumentParserContext context) throws IOException { if (fieldType().dims == null) { int currentDims = -1; while (XContentParser.Token.END_ARRAY != context.parser().nextToken()) { - int dims = fieldType().elementType.parseDimensionCount(context); + int dims = fieldType().element.parseDimensionCount(context); if (currentDims == -1) { currentDims = dims; } else if (currentDims != dims) { @@ -319,10 +321,10 @@ public void parse(DocumentParserContext context) throws IOException { return; } int dims = fieldType().dims; - DenseVectorFieldMapper.ElementType elementType = fieldType().elementType; + Element element = fieldType().element; List vectors = new ArrayList<>(); while (XContentParser.Token.END_ARRAY != context.parser().nextToken()) { - VectorData vector = elementType.parseKnnVector(context, dims, (i, b) -> { + VectorData vector = element.parseKnnVector(context, dims, (i, b) -> { if (b) { checkDimensionMatches(i, context); } else { @@ -331,12 +333,12 @@ public void parse(DocumentParserContext context) throws IOException { }, null); vectors.add(vector); } - int bufferSize = elementType.getNumBytes(dims) * vectors.size(); + int bufferSize = element.getNumBytes(dims) * vectors.size(); ByteBuffer buffer = ByteBuffer.allocate(bufferSize).order(ByteOrder.LITTLE_ENDIAN); ByteBuffer magnitudeBuffer = ByteBuffer.allocate(vectors.size() * Float.BYTES).order(ByteOrder.LITTLE_ENDIAN); for (VectorData vector : vectors) { vector.addToBuffer(buffer); - magnitudeBuffer.putFloat((float) Math.sqrt(elementType.computeSquaredMagnitude(vector))); + magnitudeBuffer.putFloat((float) Math.sqrt(element.computeSquaredMagnitude(vector))); } String vectorFieldName = fieldType().name(); String vectorMagnitudeFieldName = vectorFieldName + VECTOR_MAGNITUDES_SUFFIX; @@ -444,15 +446,15 @@ public void write(XContentBuilder b) throws IOException { b.startArray(leafName()); BytesRef ref = values.binaryValue(); ByteBuffer byteBuffer = ByteBuffer.wrap(ref.bytes, ref.offset, ref.length).order(ByteOrder.LITTLE_ENDIAN); - assert ref.length % fieldType().elementType.getNumBytes(fieldType().dims) == 0; - int numVecs = ref.length / fieldType().elementType.getNumBytes(fieldType().dims); + assert ref.length % fieldType().element.getNumBytes(fieldType().dims) == 0; + int numVecs = ref.length / fieldType().element.getNumBytes(fieldType().dims); for (int i = 0; i < numVecs; i++) { b.startArray(); - int dims = fieldType().elementType == DenseVectorFieldMapper.ElementType.BIT + int dims = fieldType().element.elementType() == DenseVectorFieldMapper.ElementType.BIT ? fieldType().dims / Byte.SIZE : fieldType().dims; for (int dim = 0; dim < dims; dim++) { - fieldType().elementType.readAndWriteValue(byteBuffer, b); + fieldType().element.readAndWriteValue(byteBuffer, b); } b.endArray(); } @@ -468,15 +470,15 @@ private List> copyVectorsAsList() throws IOException { assert hasValue : "rank vector is null"; BytesRef ref = values.binaryValue(); ByteBuffer byteBuffer = ByteBuffer.wrap(ref.bytes, ref.offset, ref.length).order(ByteOrder.LITTLE_ENDIAN); - assert ref.length % fieldType().elementType.getNumBytes(fieldType().dims) == 0; - int numVecs = ref.length / fieldType().elementType.getNumBytes(fieldType().dims); + assert ref.length % fieldType().element.getNumBytes(fieldType().dims) == 0; + int numVecs = ref.length / fieldType().element.getNumBytes(fieldType().dims); List> vectors = new ArrayList<>(numVecs); for (int i = 0; i < numVecs; i++) { - int dims = fieldType().elementType == DenseVectorFieldMapper.ElementType.BIT + int dims = fieldType().element.elementType() == DenseVectorFieldMapper.ElementType.BIT ? fieldType().dims / Byte.SIZE : fieldType().dims; - switch (fieldType().elementType) { + switch (fieldType().element.elementType()) { case FLOAT -> { List vec = new ArrayList<>(dims); for (int dim = 0; dim < dims; dim++) { diff --git a/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/script/RankVectorsScoreScriptUtils.java b/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/script/RankVectorsScoreScriptUtils.java index 3d692db08ff9e..1c533e9ec88cd 100644 --- a/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/script/RankVectorsScoreScriptUtils.java +++ b/x-pack/plugin/rank-vectors/src/main/java/org/elasticsearch/xpack/rank/vectors/script/RankVectorsScoreScriptUtils.java @@ -55,7 +55,7 @@ public ByteRankVectorsFunction(ScoreScript scoreScript, RankVectorsDocValuesFiel if (queryVector.isEmpty()) { throw new IllegalArgumentException("The query vector is empty."); } - field.getElementType().checkDimensions(field.get().getDims(), queryVector.get(0).size()); + field.getElement().checkDimensions(field.get().getDims(), queryVector.get(0).size()); this.queryVector = new byte[queryVector.size()][queryVector.get(0).size()]; float[] validateValues = new float[queryVector.size()]; int lastSize = -1; @@ -72,7 +72,7 @@ public ByteRankVectorsFunction(ScoreScript scoreScript, RankVectorsDocValuesFiel this.queryVector[i][j] = value; validateValues[i] = number.floatValue(); } - field.getElementType().checkVectorBounds(validateValues); + field.getElement().checkVectorBounds(validateValues); } } @@ -118,7 +118,7 @@ public FloatRankVectorsFunction(ScoreScript scoreScript, RankVectorsDocValuesFie for (int j = 0; j < queryVector.get(i).size(); j++) { this.queryVector[i][j] = queryVector.get(i).get(j).floatValue(); } - field.getElementType().checkVectorBounds(this.queryVector[i]); + field.getElement().checkVectorBounds(this.queryVector[i]); } } } diff --git a/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapperTests.java b/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapperTests.java index 6f80d7b46f563..f53f9a1c92f0e 100644 --- a/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapperTests.java +++ b/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsFieldMapperTests.java @@ -24,6 +24,7 @@ import org.elasticsearch.index.mapper.ParsedDocument; import org.elasticsearch.index.mapper.SourceToParse; import org.elasticsearch.index.mapper.ValueFetcher; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.index.mapper.vectors.SyntheticVectorsMapperTestCase; import org.elasticsearch.index.query.SearchExecutionContext; @@ -232,7 +233,7 @@ public void testNonIndexedVector() throws Exception { assertThat(fields.get(0), instanceOf(BinaryDocValuesField.class)); // assert that after decoding the indexed value is equal to expected BytesRef vectorBR = fields.get(0).binaryValue(); - assertEquals(ElementType.FLOAT.getNumBytes(validVectors[0].length) * validVectors.length, vectorBR.length); + assertEquals(DenseVectorFieldMapper.FLOAT_ELEMENT.getNumBytes(validVectors[0].length) * validVectors.length, vectorBR.length); float[][] decodedValues = new float[validVectors.length][]; for (int i = 0; i < validVectors.length; i++) { decodedValues[i] = new float[validVectors[i].length]; diff --git a/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsScriptDocValuesTests.java b/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsScriptDocValuesTests.java index f0b00849557bd..127ad6c7dbe43 100644 --- a/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsScriptDocValuesTests.java +++ b/x-pack/plugin/rank-vectors/src/test/java/org/elasticsearch/xpack/rank/vectors/mapper/RankVectorsScriptDocValuesTests.java @@ -10,6 +10,7 @@ import org.apache.lucene.index.BinaryDocValues; import org.apache.lucene.util.BytesRef; import org.elasticsearch.index.IndexVersion; +import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.Element; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.index.mapper.vectors.RankVectorsScriptDocValues; import org.elasticsearch.script.field.vectors.ByteRankVectorsDocValuesField; @@ -300,8 +301,9 @@ public static BytesRef mockEncodeDenseVector(float[][] values, ElementType eleme if (elementType == ElementType.BIT) { dims *= Byte.SIZE; } - int numBytes = elementType.getNumBytes(dims); - ByteBuffer byteBuffer = elementType.createByteBuffer(indexVersion, numBytes * values.length); + Element element = Element.getElement(elementType); + int numBytes = element.getNumBytes(dims); + ByteBuffer byteBuffer = element.createByteBuffer(indexVersion, numBytes * values.length); for (float[] vector : values) { for (float value : vector) { if (elementType == ElementType.FLOAT) { From 8155636c29bdc9a03aab5cad86e92ab6781287e8 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Mon, 8 Sep 2025 11:14:21 +0100 Subject: [PATCH 3/4] Remove extra reference --- .../script/field/vectors/RankVectorsDocValuesField.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java index c9b33d735c065..aa99337f2cb9d 100644 --- a/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java @@ -42,7 +42,7 @@ public ElementType getElementType() { } public Element getElement() { - return DenseVectorFieldMapper.Element.getElement(elementType); + return Element.getElement(elementType); } /** From 72cbf0e49b25b83fdab718ec8ef9ca27b5ee4a98 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Mon, 8 Sep 2025 10:22:09 +0000 Subject: [PATCH 4/4] [CI] Auto commit changes from spotless --- .../script/field/vectors/RankVectorsDocValuesField.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java b/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java index aa99337f2cb9d..3a50bce8ffa95 100644 --- a/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java +++ b/server/src/main/java/org/elasticsearch/script/field/vectors/RankVectorsDocValuesField.java @@ -9,7 +9,6 @@ package org.elasticsearch.script.field.vectors; -import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.Element; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper.ElementType; import org.elasticsearch.index.mapper.vectors.RankVectorsScriptDocValues;