2929import org .elasticsearch .index .mapper .BlockLoader .DoubleBuilder ;
3030import org .elasticsearch .index .mapper .BlockLoader .IntBuilder ;
3131import org .elasticsearch .index .mapper .BlockLoader .LongBuilder ;
32+ import org .elasticsearch .index .mapper .vectors .DenseVectorFieldMapper ;
33+ import org .elasticsearch .index .mapper .vectors .DenseVectorFieldMapper .ElementType ;
3234import org .elasticsearch .index .mapper .vectors .VectorEncoderDecoder ;
3335import org .elasticsearch .search .fetch .StoredFieldsSpec ;
3436
3537import java .io .IOException ;
3638
39+ import static org .elasticsearch .index .mapper .vectors .DenseVectorFieldMapper .COSINE_MAGNITUDE_FIELD_SUFFIX ;
40+
3741/**
3842 * A reader that supports reading doc-values from a Lucene segment in Block fashion.
3943 */
@@ -511,10 +515,12 @@ public String toString() {
511515 public static class DenseVectorBlockLoader extends DocValuesBlockLoader {
512516 private final String fieldName ;
513517 private final int dimensions ;
518+ private final DenseVectorFieldMapper .DenseVectorFieldType fieldType ;
514519
515- public DenseVectorBlockLoader (String fieldName , int dimensions ) {
520+ public DenseVectorBlockLoader (String fieldName , int dimensions , DenseVectorFieldMapper . DenseVectorFieldType fieldType ) {
516521 this .fieldName = fieldName ;
517522 this .dimensions = dimensions ;
523+ this .fieldType = fieldType ;
518524 }
519525
520526 @ Override
@@ -524,9 +530,26 @@ public Builder builder(BlockFactory factory, int expectedCount) {
524530
525531 @ Override
526532 public AllReader reader (LeafReaderContext context ) throws IOException {
527- FloatVectorValues floatVectorValues = context .reader ().getFloatVectorValues (fieldName );
528- if (floatVectorValues != null ) {
529- return new DenseVectorValuesBlockReader (floatVectorValues , dimensions );
533+ switch (fieldType .getElementType ()) {
534+ case FLOAT -> {
535+ FloatVectorValues floatVectorValues = context .reader ().getFloatVectorValues (fieldName );
536+ if (floatVectorValues != null ) {
537+ if (fieldType .isNormalized ()) {
538+ return new FloatDenseVectorNormalizedValuesBlockReader (
539+ floatVectorValues ,
540+ dimensions ,
541+ context .reader ().getNumericDocValues (fieldType .name () + COSINE_MAGNITUDE_FIELD_SUFFIX )
542+ );
543+ }
544+ return new FloatDenseVectorValuesBlockReader (floatVectorValues , dimensions );
545+ }
546+ }
547+ case BYTE -> {
548+ ByteVectorValues byteVectorValues = context .reader ().getByteVectorValues (fieldName );
549+ if (byteVectorValues != null ) {
550+ return new ByteDenseVectorValuesBlockReader (byteVectorValues , dimensions );
551+ }
552+ }
530553 }
531554 return new ConstantNullsReader ();
532555 }
@@ -580,10 +603,77 @@ private void read(int doc, BlockLoader.FloatBuilder builder) throws IOException
580603 public int docId () {
581604 return iterator .docID ();
582605 }
606+ }
607+
608+ private static class FloatDenseVectorValuesBlockReader extends DenseVectorValuesBlockReader <FloatVectorValues > {
609+
610+ FloatDenseVectorValuesBlockReader (FloatVectorValues floatVectorValues , int dimensions ) {
611+ super (floatVectorValues , dimensions );
612+ }
613+
614+ protected void appendDoc (BlockLoader .FloatBuilder builder ) throws IOException {
615+ float [] floats = vectorValues .vectorValue (iterator .index ());
616+ assert floats .length == dimensions
617+ : "unexpected dimensions for vector value; expected " + dimensions + " but got " + floats .length ;
618+ for (float aFloat : floats ) {
619+ builder .appendFloat (aFloat );
620+ }
621+ }
622+
623+ @ Override
624+ public String toString () {
625+ return "BlockDocValuesReader.FloatDenseVectorValuesBlockReader" ;
626+ }
627+ }
628+
629+ private static class FloatDenseVectorNormalizedValuesBlockReader extends DenseVectorValuesBlockReader <FloatVectorValues > {
630+ private final NumericDocValues magnitudeDocValues ;
631+
632+ FloatDenseVectorNormalizedValuesBlockReader (
633+ FloatVectorValues floatVectorValues ,
634+ int dimensions ,
635+ NumericDocValues magnitudeDocValues
636+ ) {
637+ super (floatVectorValues , dimensions );
638+ this .magnitudeDocValues = magnitudeDocValues ;
639+ }
640+
641+ @ Override
642+ protected void appendDoc (BlockLoader .FloatBuilder builder ) throws IOException {
643+ float [] floats = vectorValues .vectorValue (iterator .index ());
644+ assert floats .length == dimensions
645+ : "unexpected dimensions for vector value; expected " + dimensions + " but got " + floats .length ;
646+
647+ assert magnitudeDocValues .advanceExact (iterator .docID ());
648+ float magnitude = Float .intBitsToFloat ((int ) magnitudeDocValues .longValue ());
649+ for (float aFloat : floats ) {
650+ builder .appendFloat (aFloat * magnitude );
651+ }
652+ }
653+
654+ @ Override
655+ public String toString () {
656+ return "BlockDocValuesReader.FloatDenseVectorNormalizedValuesBlockReader" ;
657+ }
658+ }
659+
660+ private static class ByteDenseVectorValuesBlockReader extends DenseVectorValuesBlockReader <ByteVectorValues > {
661+ ByteDenseVectorValuesBlockReader (ByteVectorValues floatVectorValues , int dimensions ) {
662+ super (floatVectorValues , dimensions );
663+ }
664+
665+ protected void appendDoc (BlockLoader .FloatBuilder builder ) throws IOException {
666+ byte [] bytes = vectorValues .vectorValue (iterator .index ());
667+ assert bytes .length == dimensions
668+ : "unexpected dimensions for vector value; expected " + dimensions + " but got " + bytes .length ;
669+ for (byte aFloat : bytes ) {
670+ builder .appendFloat (aFloat );
671+ }
672+ }
583673
584674 @ Override
585675 public String toString () {
586- return "BlockDocValuesReader.FloatVectorValuesBlockReader " ;
676+ return "BlockDocValuesReader.ByteDenseVectorValuesBlockReader " ;
587677 }
588678 }
589679
0 commit comments