Skip to content

Commit bd2f403

Browse files
authored
Revert 'Support script score when doc value is disabled' (opensearch-project#1662)
Signed-off-by: Ryan Bogan <[email protected]>
1 parent e608d2d commit bd2f403

8 files changed

+33
-186
lines changed

CHANGELOG.md

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1818
* Support filter and nested field in faiss engine radial search [#1652](https://github.com/opensearch-project/k-NN/pull/1652)
1919
### Enhancements
2020
* Make the HitQueue size more appropriate for exact search [#1549](https://github.com/opensearch-project/k-NN/pull/1549)
21-
* Support script score when doc value is disabled [#1573](https://github.com/opensearch-project/k-NN/pull/1573)
2221
* Implemented the Streaming Feature to stream vectors from Java to JNI layer to enable creation of larger segments for vector indices [#1604](https://github.com/opensearch-project/k-NN/pull/1604)
2322
* Remove unnecessary toString conversion of vector field and added some minor optimization in KNNCodec [1613](https://github.com/opensearch-project/k-NN/pull/1613)
2423
* Serialize all models into cluster metadata [#1499](https://github.com/opensearch-project/k-NN/pull/1499)

src/main/java/org/opensearch/knn/index/KNNVectorDVLeafFieldData.java

+4-24
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55

66
package org.opensearch.knn.index;
77

8+
import org.apache.lucene.index.BinaryDocValues;
89
import org.apache.lucene.index.DocValues;
9-
import org.apache.lucene.index.FieldInfo;
1010
import org.apache.lucene.index.LeafReader;
11-
import org.apache.lucene.search.DocIdSetIterator;
1211
import org.opensearch.index.fielddata.LeafFieldData;
1312
import org.opensearch.index.fielddata.ScriptDocValues;
1413
import org.opensearch.index.fielddata.SortedBinaryDocValues;
@@ -40,29 +39,10 @@ public long ramBytesUsed() {
4039
@Override
4140
public ScriptDocValues<float[]> getScriptValues() {
4241
try {
43-
FieldInfo fieldInfo = reader.getFieldInfos().fieldInfo(fieldName);
44-
if (fieldInfo == null) {
45-
return KNNVectorScriptDocValues.emptyValues(fieldName, vectorDataType);
46-
}
47-
48-
DocIdSetIterator values;
49-
if (fieldInfo.hasVectorValues()) {
50-
switch (fieldInfo.getVectorEncoding()) {
51-
case FLOAT32:
52-
values = reader.getFloatVectorValues(fieldName);
53-
break;
54-
case BYTE:
55-
values = reader.getByteVectorValues(fieldName);
56-
break;
57-
default:
58-
throw new IllegalStateException("Unsupported Lucene vector encoding: " + fieldInfo.getVectorEncoding());
59-
}
60-
} else {
61-
values = DocValues.getBinary(reader, fieldName);
62-
}
63-
return KNNVectorScriptDocValues.create(values, fieldName, vectorDataType);
42+
BinaryDocValues values = DocValues.getBinary(reader, fieldName);
43+
return new KNNVectorScriptDocValues(values, fieldName, vectorDataType);
6444
} catch (IOException e) {
65-
throw new IllegalStateException("Cannot load values for knn vector field: " + fieldName, e);
45+
throw new IllegalStateException("Cannot load doc values for knn vector field: " + fieldName, e);
6646
}
6747
}
6848

src/main/java/org/opensearch/knn/index/KNNVectorScriptDocValues.java

+11-97
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,30 @@
66
package org.opensearch.knn.index;
77

88
import java.io.IOException;
9-
import java.util.Objects;
10-
import lombok.AccessLevel;
119
import lombok.Getter;
1210
import lombok.RequiredArgsConstructor;
1311
import org.apache.lucene.index.BinaryDocValues;
14-
import org.apache.lucene.index.ByteVectorValues;
15-
import org.apache.lucene.index.FloatVectorValues;
16-
import org.apache.lucene.search.DocIdSetIterator;
1712
import org.opensearch.ExceptionsHelper;
1813
import org.opensearch.index.fielddata.ScriptDocValues;
1914

20-
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
21-
public abstract class KNNVectorScriptDocValues extends ScriptDocValues<float[]> {
15+
import java.io.IOException;
16+
17+
@RequiredArgsConstructor
18+
public final class KNNVectorScriptDocValues extends ScriptDocValues<float[]> {
2219

23-
private final DocIdSetIterator vectorValues;
20+
private final BinaryDocValues binaryDocValues;
2421
private final String fieldName;
2522
@Getter
2623
private final VectorDataType vectorDataType;
2724
private boolean docExists = false;
2825

2926
@Override
3027
public void setNextDocId(int docId) throws IOException {
31-
docExists = vectorValues.docID() == docId || vectorValues.advance(docId) == docId;
28+
if (binaryDocValues.advanceExact(docId)) {
29+
docExists = true;
30+
return;
31+
}
32+
docExists = false;
3233
}
3334

3435
public float[] getValue() {
@@ -43,14 +44,12 @@ public float[] getValue() {
4344
throw new IllegalStateException(errorMessage);
4445
}
4546
try {
46-
return doGetValue();
47+
return vectorDataType.getVectorFromBytesRef(binaryDocValues.binaryValue());
4748
} catch (IOException e) {
4849
throw ExceptionsHelper.convertToOpenSearchException(e);
4950
}
5051
}
5152

52-
protected abstract float[] doGetValue() throws IOException;
53-
5453
@Override
5554
public int size() {
5655
return docExists ? 1 : 0;
@@ -60,89 +59,4 @@ public int size() {
6059
public float[] get(int i) {
6160
throw new UnsupportedOperationException("knn vector does not support this operation");
6261
}
63-
64-
/**
65-
* Creates a KNNVectorScriptDocValues object based on the provided parameters.
66-
*
67-
* @param values The DocIdSetIterator representing the vector values.
68-
* @param fieldName The name of the field.
69-
* @param vectorDataType The data type of the vector.
70-
* @return A KNNVectorScriptDocValues object based on the type of the values.
71-
* @throws IllegalArgumentException If the type of values is unsupported.
72-
*/
73-
public static KNNVectorScriptDocValues create(DocIdSetIterator values, String fieldName, VectorDataType vectorDataType) {
74-
Objects.requireNonNull(values, "values must not be null");
75-
if (values instanceof ByteVectorValues) {
76-
return new KNNByteVectorScriptDocValues((ByteVectorValues) values, fieldName, vectorDataType);
77-
} else if (values instanceof FloatVectorValues) {
78-
return new KNNFloatVectorScriptDocValues((FloatVectorValues) values, fieldName, vectorDataType);
79-
} else if (values instanceof BinaryDocValues) {
80-
return new KNNNativeVectorScriptDocValues((BinaryDocValues) values, fieldName, vectorDataType);
81-
} else {
82-
throw new IllegalArgumentException("Unsupported values type: " + values.getClass());
83-
}
84-
}
85-
86-
private static final class KNNByteVectorScriptDocValues extends KNNVectorScriptDocValues {
87-
private final ByteVectorValues values;
88-
89-
KNNByteVectorScriptDocValues(ByteVectorValues values, String field, VectorDataType type) {
90-
super(values, field, type);
91-
this.values = values;
92-
}
93-
94-
@Override
95-
protected float[] doGetValue() throws IOException {
96-
byte[] bytes = values.vectorValue();
97-
float[] value = new float[bytes.length];
98-
for (int i = 0; i < bytes.length; i++) {
99-
value[i] = (float) bytes[i];
100-
}
101-
return value;
102-
}
103-
}
104-
105-
private static final class KNNFloatVectorScriptDocValues extends KNNVectorScriptDocValues {
106-
private final FloatVectorValues values;
107-
108-
KNNFloatVectorScriptDocValues(FloatVectorValues values, String field, VectorDataType type) {
109-
super(values, field, type);
110-
this.values = values;
111-
}
112-
113-
@Override
114-
protected float[] doGetValue() throws IOException {
115-
return values.vectorValue();
116-
}
117-
}
118-
119-
private static final class KNNNativeVectorScriptDocValues extends KNNVectorScriptDocValues {
120-
private final BinaryDocValues values;
121-
122-
KNNNativeVectorScriptDocValues(BinaryDocValues values, String field, VectorDataType type) {
123-
super(values, field, type);
124-
this.values = values;
125-
}
126-
127-
@Override
128-
protected float[] doGetValue() throws IOException {
129-
return getVectorDataType().getVectorFromBytesRef(values.binaryValue());
130-
}
131-
}
132-
133-
/**
134-
* Creates an empty KNNVectorScriptDocValues object based on the provided field name and vector data type.
135-
*
136-
* @param fieldName The name of the field.
137-
* @param type The data type of the vector.
138-
* @return An empty KNNVectorScriptDocValues object.
139-
*/
140-
public static KNNVectorScriptDocValues emptyValues(String fieldName, VectorDataType type) {
141-
return new KNNVectorScriptDocValues(DocIdSetIterator.empty(), fieldName, type) {
142-
@Override
143-
protected float[] doGetValue() throws IOException {
144-
throw new UnsupportedOperationException("empty values");
145-
}
146-
};
147-
}
14862
}

src/test/java/org/opensearch/knn/index/KNNVectorScriptDocValuesTests.java

+13-48
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,7 @@
55

66
package org.opensearch.knn.index;
77

8-
import org.apache.lucene.document.Field;
9-
import org.apache.lucene.document.KnnByteVectorField;
10-
import org.apache.lucene.document.KnnFloatVectorField;
11-
import org.apache.lucene.index.BinaryDocValues;
12-
import org.apache.lucene.index.ByteVectorValues;
13-
import org.apache.lucene.index.DocValues;
14-
import org.apache.lucene.index.FloatVectorValues;
15-
import org.apache.lucene.index.LeafReader;
16-
import org.apache.lucene.search.DocIdSetIterator;
8+
import org.apache.lucene.index.LeafReaderContext;
179
import org.opensearch.knn.KNNTestCase;
1810
import org.apache.lucene.tests.analysis.MockAnalyzer;
1911
import org.apache.lucene.document.BinaryDocValuesField;
@@ -41,39 +33,26 @@ public class KNNVectorScriptDocValuesTests extends KNNTestCase {
4133
public void setUp() throws Exception {
4234
super.setUp();
4335
directory = newDirectory();
44-
Class<? extends DocIdSetIterator> valuesClass = randomFrom(BinaryDocValues.class, ByteVectorValues.class, FloatVectorValues.class);
45-
createKNNVectorDocument(directory, valuesClass);
36+
createKNNVectorDocument(directory);
4637
reader = DirectoryReader.open(directory);
47-
LeafReader leafReader = reader.getContext().leaves().get(0).reader();
48-
DocIdSetIterator vectorValues;
49-
if (BinaryDocValues.class.equals(valuesClass)) {
50-
vectorValues = DocValues.getBinary(leafReader, MOCK_INDEX_FIELD_NAME);
51-
} else if (ByteVectorValues.class.equals(valuesClass)) {
52-
vectorValues = leafReader.getByteVectorValues(MOCK_INDEX_FIELD_NAME);
53-
} else {
54-
vectorValues = leafReader.getFloatVectorValues(MOCK_INDEX_FIELD_NAME);
55-
}
56-
57-
scriptDocValues = KNNVectorScriptDocValues.create(vectorValues, MOCK_INDEX_FIELD_NAME, VectorDataType.FLOAT);
38+
LeafReaderContext leafReaderContext = reader.getContext().leaves().get(0);
39+
scriptDocValues = new KNNVectorScriptDocValues(
40+
leafReaderContext.reader().getBinaryDocValues(MOCK_INDEX_FIELD_NAME),
41+
MOCK_INDEX_FIELD_NAME,
42+
VectorDataType.FLOAT
43+
);
5844
}
5945

60-
private void createKNNVectorDocument(Directory directory, Class<? extends DocIdSetIterator> valuesClass) throws IOException {
46+
private void createKNNVectorDocument(Directory directory) throws IOException {
6147
IndexWriterConfig conf = newIndexWriterConfig(new MockAnalyzer(random()));
6248
IndexWriter writer = new IndexWriter(directory, conf);
6349
Document knnDocument = new Document();
64-
Field field;
65-
if (BinaryDocValues.class.equals(valuesClass)) {
66-
field = new BinaryDocValuesField(
50+
knnDocument.add(
51+
new BinaryDocValuesField(
6752
MOCK_INDEX_FIELD_NAME,
6853
new VectorField(MOCK_INDEX_FIELD_NAME, SAMPLE_VECTOR_DATA, new FieldType()).binaryValue()
69-
);
70-
} else if (ByteVectorValues.class.equals(valuesClass)) {
71-
field = new KnnByteVectorField(MOCK_INDEX_FIELD_NAME, SAMPLE_BYTE_VECTOR_DATA);
72-
} else {
73-
field = new KnnFloatVectorField(MOCK_INDEX_FIELD_NAME, SAMPLE_VECTOR_DATA);
74-
}
75-
76-
knnDocument.add(field);
54+
)
55+
);
7756
writer.addDocument(knnDocument);
7857
writer.commit();
7958
writer.close();
@@ -105,18 +84,4 @@ public void testSize() throws IOException {
10584
public void testGet() throws IOException {
10685
expectThrows(UnsupportedOperationException.class, () -> scriptDocValues.get(0));
10786
}
108-
109-
public void testUnsupportedValues() throws IOException {
110-
expectThrows(
111-
IllegalArgumentException.class,
112-
() -> KNNVectorScriptDocValues.create(DocValues.emptyNumeric(), MOCK_INDEX_FIELD_NAME, VectorDataType.FLOAT)
113-
);
114-
}
115-
116-
public void testEmptyValues() throws IOException {
117-
KNNVectorScriptDocValues values = KNNVectorScriptDocValues.emptyValues(MOCK_INDEX_FIELD_NAME, VectorDataType.FLOAT);
118-
assertEquals(0, values.size());
119-
scriptDocValues.setNextDocId(0);
120-
assertEquals(0, values.size());
121-
}
12287
}

src/test/java/org/opensearch/knn/index/VectorDataTypeTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private KNNVectorScriptDocValues getKNNFloatVectorScriptDocValues() {
5757
createKNNFloatVectorDocument(directory);
5858
reader = DirectoryReader.open(directory);
5959
LeafReaderContext leafReaderContext = reader.getContext().leaves().get(0);
60-
return KNNVectorScriptDocValues.create(
60+
return new KNNVectorScriptDocValues(
6161
leafReaderContext.reader().getBinaryDocValues(VectorDataTypeTests.MOCK_FLOAT_INDEX_FIELD_NAME),
6262
VectorDataTypeTests.MOCK_FLOAT_INDEX_FIELD_NAME,
6363
VectorDataType.FLOAT
@@ -70,7 +70,7 @@ private KNNVectorScriptDocValues getKNNByteVectorScriptDocValues() {
7070
createKNNByteVectorDocument(directory);
7171
reader = DirectoryReader.open(directory);
7272
LeafReaderContext leafReaderContext = reader.getContext().leaves().get(0);
73-
return KNNVectorScriptDocValues.create(
73+
return new KNNVectorScriptDocValues(
7474
leafReaderContext.reader().getBinaryDocValues(VectorDataTypeTests.MOCK_BYTE_INDEX_FIELD_NAME),
7575
VectorDataTypeTests.MOCK_BYTE_INDEX_FIELD_NAME,
7676
VectorDataType.BYTE

src/test/java/org/opensearch/knn/plugin/script/KNNScoringUtilTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ public KNNVectorScriptDocValues getScriptDocValues(String fieldName) throws IOEx
280280
if (scriptDocValues == null) {
281281
reader = DirectoryReader.open(directory);
282282
LeafReaderContext leafReaderContext = reader.getContext().leaves().get(0);
283-
scriptDocValues = KNNVectorScriptDocValues.create(
283+
scriptDocValues = new KNNVectorScriptDocValues(
284284
leafReaderContext.reader().getBinaryDocValues(fieldName),
285285
fieldName,
286286
VectorDataType.FLOAT

src/test/java/org/opensearch/knn/plugin/script/KNNScriptScoringIT.java

+1-10
Original file line numberDiff line numberDiff line change
@@ -612,16 +612,7 @@ private List<String> createMappers(int dimensions) throws Exception {
612612
dimensions,
613613
KNNConstants.METHOD_HNSW,
614614
KNNEngine.LUCENE.getName(),
615-
SpaceType.DEFAULT.getValue(),
616-
true
617-
),
618-
createKnnIndexMapping(
619-
FIELD_NAME,
620-
dimensions,
621-
KNNConstants.METHOD_HNSW,
622-
KNNEngine.LUCENE.getName(),
623-
SpaceType.DEFAULT.getValue(),
624-
false
615+
SpaceType.DEFAULT.getValue()
625616
)
626617
);
627618
}

src/test/java/org/opensearch/knn/plugin/script/PainlessScriptIT.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -563,9 +563,7 @@ public void testL2ScriptingWithLuceneBackedIndex() throws Exception {
563563
new MethodComponentContext(METHOD_HNSW, Collections.emptyMap())
564564
);
565565
properties.add(
566-
new MappingProperty(FIELD_NAME, KNNVectorFieldMapper.CONTENT_TYPE).dimension("2")
567-
.knnMethodContext(knnMethodContext)
568-
.docValues(randomBoolean())
566+
new MappingProperty(FIELD_NAME, KNNVectorFieldMapper.CONTENT_TYPE).dimension("2").knnMethodContext(knnMethodContext)
569567
);
570568

571569
String source = String.format("1/(1 + l2Squared([1.0f, 1.0f], doc['%s']))", FIELD_NAME);

0 commit comments

Comments
 (0)