@@ -863,6 +863,74 @@ public void testANNWithFilterQuery_whenExactSearchViaThresholdSetting_thenSucces
863
863
assertTrue (Comparators .isInOrder (actualDocIds , Comparator .naturalOrder ()));
864
864
}
865
865
866
+ /**
867
+ * This test ensure that we do the exact search when threshold settings are correct and not using filteredIds<=K
868
+ * condition to do exact search on binary index
869
+ * FilteredIdThreshold: 10
870
+ * FilteredIdThresholdPct: 10%
871
+ * FilteredIdsCount: 6
872
+ * liveDocs : null, as there is no deleted documents
873
+ * MaxDoc: 100
874
+ * K : 1
875
+ */
876
+ @ SneakyThrows
877
+ public void testANNWithFilterQuery_whenExactSearchViaThresholdSettingOnBinaryIndex_thenSuccess () {
878
+ knnSettingsMockedStatic .when (() -> KNNSettings .getFilteredExactSearchThreshold (INDEX_NAME )).thenReturn (10 );
879
+ byte [] vector = new byte [] { 1 , 3 };
880
+ int k = 1 ;
881
+ final int [] filterDocIds = new int [] { 0 , 1 , 2 , 3 , 4 , 5 };
882
+
883
+ final LeafReaderContext leafReaderContext = mock (LeafReaderContext .class );
884
+ final SegmentReader reader = mock (SegmentReader .class );
885
+ when (leafReaderContext .reader ()).thenReturn (reader );
886
+ when (reader .maxDoc ()).thenReturn (100 );
887
+ when (reader .getLiveDocs ()).thenReturn (null );
888
+ final Weight filterQueryWeight = mock (Weight .class );
889
+ final Scorer filterScorer = mock (Scorer .class );
890
+ when (filterQueryWeight .scorer (leafReaderContext )).thenReturn (filterScorer );
891
+
892
+ when (filterScorer .iterator ()).thenReturn (DocIdSetIterator .all (filterDocIds .length ));
893
+
894
+ final KNNQuery query = new KNNQuery (FIELD_NAME , BYTE_QUERY_VECTOR , k , INDEX_NAME , FILTER_QUERY , null , VectorDataType .BINARY );
895
+
896
+ final float boost = (float ) randomDoubleBetween (0 , 10 , true );
897
+ final KNNWeight knnWeight = new KNNWeight (query , boost , filterQueryWeight );
898
+ final Map <String , String > attributesMap = ImmutableMap .of (
899
+ KNN_ENGINE ,
900
+ KNNEngine .FAISS .getName (),
901
+ SPACE_TYPE ,
902
+ SpaceType .HAMMING_BIT .name (),
903
+ PARAMETERS ,
904
+ String .format (Locale .ROOT , "{\" %s\" :\" %s\" }" , INDEX_DESCRIPTION_PARAMETER , "BHNSW32" )
905
+ );
906
+ final FieldInfos fieldInfos = mock (FieldInfos .class );
907
+ final FieldInfo fieldInfo = mock (FieldInfo .class );
908
+ final BinaryDocValues binaryDocValues = mock (BinaryDocValues .class );
909
+ when (reader .getFieldInfos ()).thenReturn (fieldInfos );
910
+ when (fieldInfos .fieldInfo (any ())).thenReturn (fieldInfo );
911
+ when (fieldInfo .attributes ()).thenReturn (attributesMap );
912
+ when (fieldInfo .getAttribute (SPACE_TYPE )).thenReturn (SpaceType .HAMMING_BIT .getValue ());
913
+ when (fieldInfo .getName ()).thenReturn (FIELD_NAME );
914
+ when (reader .getBinaryDocValues (FIELD_NAME )).thenReturn (binaryDocValues );
915
+ when (binaryDocValues .advance (0 )).thenReturn (0 );
916
+ BytesRef vectorByteRef = new BytesRef (vector );
917
+ when (binaryDocValues .binaryValue ()).thenReturn (vectorByteRef );
918
+
919
+ final KNNScorer knnScorer = (KNNScorer ) knnWeight .scorer (leafReaderContext );
920
+ assertNotNull (knnScorer );
921
+ final DocIdSetIterator docIdSetIterator = knnScorer .iterator ();
922
+ assertNotNull (docIdSetIterator );
923
+ assertEquals (EXACT_SEARCH_DOC_ID_TO_SCORES .size (), docIdSetIterator .cost ());
924
+
925
+ final List <Integer > actualDocIds = new ArrayList <>();
926
+ for (int docId = docIdSetIterator .nextDoc (); docId != NO_MORE_DOCS ; docId = docIdSetIterator .nextDoc ()) {
927
+ actualDocIds .add (docId );
928
+ assertEquals (BINARY_EXACT_SEARCH_DOC_ID_TO_SCORES .get (docId ) * boost , knnScorer .score (), 0.01f );
929
+ }
930
+ assertEquals (docIdSetIterator .cost (), actualDocIds .size ());
931
+ assertTrue (Comparators .isInOrder (actualDocIds , Comparator .naturalOrder ()));
932
+ }
933
+
866
934
@ SneakyThrows
867
935
public void testANNWithFilterQuery_whenEmptyFilterIds_thenReturnEarly () {
868
936
final LeafReaderContext leafReaderContext = mock (LeafReaderContext .class );
0 commit comments