38
38
39
39
import java .io .IOException ;
40
40
41
+ import static org .elasticsearch .index .mapper .vectors .DenseVectorFieldMapper .COSINE_MAGNITUDE_FIELD_SUFFIX ;
41
42
import static org .elasticsearch .index .mapper .vectors .DenseVectorFieldMapper .ElementType .BYTE ;
42
43
43
44
/**
@@ -540,6 +541,11 @@ public AllReader reader(LeafReaderContext context) throws IOException {
540
541
case FLOAT -> {
541
542
FloatVectorValues floatVectorValues = context .reader ().getFloatVectorValues (fieldName );
542
543
if (floatVectorValues != null ) {
544
+ if (fieldType .isNormalized ()) {
545
+ NumericDocValues magnitudeDocValues = context .reader ()
546
+ .getNumericDocValues (fieldType .name () + COSINE_MAGNITUDE_FIELD_SUFFIX );
547
+ return new FloatDenseVectorNormalizedValuesBlockReader (floatVectorValues , dimensions , magnitudeDocValues );
548
+ }
543
549
return new FloatDenseVectorValuesBlockReader (floatVectorValues , dimensions );
544
550
}
545
551
}
@@ -584,6 +590,9 @@ public void read(int docId, BlockLoader.StoredFields storedFields, Builder build
584
590
}
585
591
586
592
private void read (int doc , BlockLoader .FloatBuilder builder ) throws IOException {
593
+ assert vectorValues .dimension () == dimensions
594
+ : "unexpected dimensions for vector value; expected " + dimensions + " but got " + vectorValues .dimension ();
595
+
587
596
if (iterator .docID () > doc ) {
588
597
builder .appendNull ();
589
598
} else if (iterator .docID () == doc || iterator .advance (doc ) == doc ) {
@@ -611,8 +620,6 @@ private static class FloatDenseVectorValuesBlockReader extends DenseVectorValues
611
620
612
621
protected void appendDoc (BlockLoader .FloatBuilder builder ) throws IOException {
613
622
float [] floats = vectorValues .vectorValue (iterator .index ());
614
- assert floats .length == dimensions
615
- : "unexpected dimensions for vector value; expected " + dimensions + " but got " + floats .length ;
616
623
for (float aFloat : floats ) {
617
624
builder .appendFloat (aFloat );
618
625
}
@@ -624,15 +631,45 @@ public String toString() {
624
631
}
625
632
}
626
633
634
+ private static class FloatDenseVectorNormalizedValuesBlockReader extends DenseVectorValuesBlockReader <FloatVectorValues > {
635
+ private final NumericDocValues magnitudeDocValues ;
636
+
637
+ FloatDenseVectorNormalizedValuesBlockReader (
638
+ FloatVectorValues floatVectorValues ,
639
+ int dimensions ,
640
+ NumericDocValues magnitudeDocValues
641
+ ) {
642
+ super (floatVectorValues , dimensions );
643
+ this .magnitudeDocValues = magnitudeDocValues ;
644
+ }
645
+
646
+ @ Override
647
+ protected void appendDoc (BlockLoader .FloatBuilder builder ) throws IOException {
648
+ float magnitude = 1.0f ;
649
+ // If all vectors are normalized, no doc values will be present. The vector may be normalized already, so we may not have a
650
+ // stored magnitude for all docs
651
+ if ((magnitudeDocValues != null ) && magnitudeDocValues .advanceExact (iterator .docID ())) {
652
+ magnitude = Float .intBitsToFloat ((int ) magnitudeDocValues .longValue ());
653
+ }
654
+ float [] floats = vectorValues .vectorValue (iterator .index ());
655
+ for (float aFloat : floats ) {
656
+ builder .appendFloat (aFloat * magnitude );
657
+ }
658
+ }
659
+
660
+ @ Override
661
+ public String toString () {
662
+ return "BlockDocValuesReader.FloatDenseVectorNormalizedValuesBlockReader" ;
663
+ }
664
+ }
665
+
627
666
private static class ByteDenseVectorValuesBlockReader extends DenseVectorValuesBlockReader <ByteVectorValues > {
628
667
ByteDenseVectorValuesBlockReader (ByteVectorValues floatVectorValues , int dimensions ) {
629
668
super (floatVectorValues , dimensions );
630
669
}
631
670
632
671
protected void appendDoc (BlockLoader .FloatBuilder builder ) throws IOException {
633
672
byte [] bytes = vectorValues .vectorValue (iterator .index ());
634
- assert bytes .length == dimensions
635
- : "unexpected dimensions for vector value; expected " + dimensions + " but got " + bytes .length ;
636
673
for (byte aFloat : bytes ) {
637
674
builder .appendFloat (aFloat );
638
675
}
0 commit comments