3232import org .elasticsearch .core .IOUtils ;
3333import org .elasticsearch .search .vectors .IVFKnnSearchStrategy ;
3434
35+ import java .io .Closeable ;
3536import java .io .IOException ;
37+ import java .util .ArrayList ;
38+ import java .util .Collections ;
39+ import java .util .List ;
40+ import java .util .Map ;
3641
3742import static org .apache .lucene .codecs .lucene99 .Lucene99HnswVectorsReader .SIMILARITY_FUNCTIONS ;
3843import static org .elasticsearch .index .codec .vectors .diskbbq .ES920DiskBBQVectorsFormat .DYNAMIC_VISIT_RATIO ;
@@ -46,14 +51,14 @@ public abstract class IVFVectorsReader extends KnnVectorsReader {
4651 private final SegmentReadState state ;
4752 private final FieldInfos fieldInfos ;
4853 protected final IntObjectHashMap <FieldEntry > fields ;
49- private final FlatVectorsReader rawVectorsReader ;
54+ private final Map < String , FlatVectorsReader > rawVectorReaders ;
5055
5156 @ SuppressWarnings ("this-escape" )
52- protected IVFVectorsReader (SegmentReadState state , FlatVectorsReader rawVectorsReader ) throws IOException {
57+ protected IVFVectorsReader (SegmentReadState state , Map < String , FlatVectorsReader > rawVectorReaders ) throws IOException {
5358 this .state = state ;
5459 this .fieldInfos = state .fieldInfos ;
55- this .rawVectorsReader = rawVectorsReader ;
5660 this .fields = new IntObjectHashMap <>();
61+ this .rawVectorReaders = rawVectorReaders ;
5762 String meta = IndexFileNames .segmentFileName (
5863 state .segmentInfo .name ,
5964 state .segmentSuffix ,
@@ -156,6 +161,7 @@ private void readFields(ChecksumIndexInput meta) throws IOException {
156161 }
157162
158163 private FieldEntry readField (IndexInput input , FieldInfo info ) throws IOException {
164+ final String rawVectorFormat = input .readString ();
159165 final VectorEncoding vectorEncoding = readVectorEncoding (input );
160166 final VectorSimilarityFunction similarityFunction = readSimilarityFunction (input );
161167 if (similarityFunction != info .getVectorSimilarityFunction ()) {
@@ -182,6 +188,7 @@ private FieldEntry readField(IndexInput input, FieldInfo info) throws IOExceptio
182188 globalCentroidDp = Float .intBitsToFloat (input .readInt ());
183189 }
184190 return new FieldEntry (
191+ rawVectorFormat ,
185192 similarityFunction ,
186193 vectorEncoding ,
187194 numCentroids ,
@@ -212,26 +219,46 @@ private static VectorEncoding readVectorEncoding(DataInput input) throws IOExcep
212219
213220 @ Override
214221 public final void checkIntegrity () throws IOException {
215- rawVectorsReader .checkIntegrity ();
222+ for (var reader : rawVectorReaders .values ()) {
223+ reader .checkIntegrity ();
224+ }
216225 CodecUtil .checksumEntireFile (ivfCentroids );
217226 CodecUtil .checksumEntireFile (ivfClusters );
218227 }
219228
229+ private FieldEntry getFieldEntryOrThrow (String field ) {
230+ final FieldInfo info = fieldInfos .fieldInfo (field );
231+ final FieldEntry entry ;
232+ if (info == null || (entry = fields .get (info .number )) == null ) {
233+ throw new IllegalArgumentException ("field=\" " + field + "\" not found" );
234+ }
235+ return entry ;
236+ }
237+
238+ private FlatVectorsReader getReaderForField (String field ) {
239+ var formatName = getFieldEntryOrThrow (field ).rawVectorFormatName ;
240+ FlatVectorsReader reader = rawVectorReaders .get (formatName );
241+ if (reader == null ) throw new IllegalArgumentException (
242+ "Could not find raw vector format [" + formatName + "] for field [" + field + "]"
243+ );
244+ return reader ;
245+ }
246+
220247 @ Override
221248 public final FloatVectorValues getFloatVectorValues (String field ) throws IOException {
222- return rawVectorsReader .getFloatVectorValues (field );
249+ return getReaderForField ( field ) .getFloatVectorValues (field );
223250 }
224251
225252 @ Override
226253 public final ByteVectorValues getByteVectorValues (String field ) throws IOException {
227- return rawVectorsReader .getByteVectorValues (field );
254+ return getReaderForField ( field ) .getByteVectorValues (field );
228255 }
229256
230257 @ Override
231258 public final void search (String field , float [] target , KnnCollector knnCollector , Bits acceptDocs ) throws IOException {
232259 final FieldInfo fieldInfo = state .fieldInfos .fieldInfo (field );
233260 if (fieldInfo .getVectorEncoding ().equals (VectorEncoding .FLOAT32 ) == false ) {
234- rawVectorsReader .search (field , target , knnCollector , acceptDocs );
261+ getReaderForField ( field ) .search (field , target , knnCollector , acceptDocs );
235262 return ;
236263 }
237264 if (fieldInfo .getVectorDimension () != target .length ) {
@@ -243,7 +270,7 @@ public final void search(String field, float[] target, KnnCollector knnCollector
243270 if (acceptDocs instanceof BitSet bitSet ) {
244271 percentFiltered = Math .max (0f , Math .min (1f , (float ) bitSet .approximateCardinality () / bitSet .length ()));
245272 }
246- int numVectors = rawVectorsReader .getFloatVectorValues (field ).size ();
273+ int numVectors = getReaderForField ( field ) .getFloatVectorValues (field ).size ();
247274 float visitRatio = DYNAMIC_VISIT_RATIO ;
248275 // Search strategy may be null if this is being called from checkIndex (e.g. from a test)
249276 if (knnCollector .getSearchStrategy () instanceof IVFKnnSearchStrategy ivfSearchStrategy ) {
@@ -309,7 +336,7 @@ public final void search(String field, float[] target, KnnCollector knnCollector
309336 @ Override
310337 public final void search (String field , byte [] target , KnnCollector knnCollector , Bits acceptDocs ) throws IOException {
311338 final FieldInfo fieldInfo = state .fieldInfos .fieldInfo (field );
312- final ByteVectorValues values = rawVectorsReader .getByteVectorValues (field );
339+ final ByteVectorValues values = getReaderForField ( field ) .getByteVectorValues (field );
313340 for (int i = 0 ; i < values .size (); i ++) {
314341 final float score = fieldInfo .getVectorSimilarityFunction ().compare (target , values .vectorValue (i ));
315342 knnCollector .collect (values .ordToDoc (i ), score );
@@ -321,10 +348,13 @@ public final void search(String field, byte[] target, KnnCollector knnCollector,
321348
322349 @ Override
323350 public void close () throws IOException {
324- IOUtils .close (rawVectorsReader , ivfCentroids , ivfClusters );
351+ List <Closeable > closeables = new ArrayList <>(rawVectorReaders .values ());
352+ Collections .addAll (closeables , ivfCentroids , ivfClusters );
353+ IOUtils .close (closeables );
325354 }
326355
327356 protected record FieldEntry (
357+ String rawVectorFormatName ,
328358 VectorSimilarityFunction similarityFunction ,
329359 VectorEncoding vectorEncoding ,
330360 int numCentroids ,
0 commit comments