4040import org .elasticsearch .inference .WeightedToken ;
4141import org .elasticsearch .search .lookup .Source ;
4242import org .elasticsearch .search .vectors .SparseVectorQueryWrapper ;
43+ import org .elasticsearch .test .ESTestCase ;
4344import org .elasticsearch .test .index .IndexVersionUtils ;
4445import org .elasticsearch .xcontent .ToXContent ;
4546import org .elasticsearch .xcontent .XContentBuilder ;
5556import java .util .LinkedHashMap ;
5657import java .util .List ;
5758import java .util .Map ;
59+ import java .util .NavigableSet ;
5860import java .util .Set ;
5961import java .util .TreeMap ;
6062import java .util .stream .Collectors ;
6163import java .util .stream .Stream ;
6264
65+ import static org .elasticsearch .index .IndexVersions .NEW_SPARSE_VECTOR ;
6366import static org .elasticsearch .index .IndexVersions .SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT ;
67+ import static org .elasticsearch .index .IndexVersions .SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT_BACKPORT_8_X ;
6468import static org .elasticsearch .index .IndexVersions .UPGRADE_TO_LUCENE_10_0_0 ;
65- import static org .elasticsearch .index .mapper .vectors .SparseVectorFieldMapper .NEW_SPARSE_VECTOR_INDEX_VERSION ;
66- import static org .elasticsearch .index .mapper .vectors .SparseVectorFieldMapper .PREVIOUS_SPARSE_VECTOR_INDEX_VERSION ;
67- import static org .elasticsearch .index .mapper .vectors .SparseVectorFieldMapper .SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_VERSION ;
6869import static org .elasticsearch .test .hamcrest .ElasticsearchAssertions .assertToXContentEquivalent ;
6970import static org .elasticsearch .xcontent .XContentFactory .jsonBuilder ;
7071import static org .hamcrest .Matchers .containsString ;
@@ -286,7 +287,7 @@ public void testDefaultsWithAndWithoutIncludeDefaultsOlderIndexVersion() throws
286287 IndexVersion indexVersion = IndexVersionUtils .randomVersionBetween (
287288 random (),
288289 UPGRADE_TO_LUCENE_10_0_0 ,
289- IndexVersionUtils .getPreviousVersion (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_VERSION )
290+ IndexVersionUtils .getPreviousVersion (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT )
290291 );
291292
292293 XContentBuilder orig = JsonXContent .contentBuilder ().startObject ();
@@ -501,21 +502,21 @@ protected IngestScriptSupport ingestScriptSupport() {
501502 @ Override
502503 protected String [] getParseMinimalWarnings (IndexVersion indexVersion ) {
503504 String [] additionalWarnings = null ;
504- if (indexVersion .before (PREVIOUS_SPARSE_VECTOR_INDEX_VERSION )) {
505+ if (indexVersion .before (IndexVersions . V_8_0_0 )) {
505506 additionalWarnings = new String [] { SparseVectorFieldMapper .ERROR_MESSAGE_7X };
506507 }
507508 return Strings .concatStringArrays (super .getParseMinimalWarnings (indexVersion ), additionalWarnings );
508509 }
509510
510511 @ Override
511512 protected IndexVersion boostNotAllowedIndexVersion () {
512- return NEW_SPARSE_VECTOR_INDEX_VERSION ;
513+ return NEW_SPARSE_VECTOR ;
513514 }
514515
515516 public void testSparseVectorUnsupportedIndex () {
516517 IndexVersion version = IndexVersionUtils .randomVersionBetween (
517518 random (),
518- PREVIOUS_SPARSE_VECTOR_INDEX_VERSION ,
519+ IndexVersions . V_8_0_0 ,
519520 IndexVersions .FIRST_DETACHED_INDEX_VERSION
520521 );
521522 Exception e = expectThrows (MapperParsingException .class , () -> createMapperService (version , fieldMapping (b -> {
@@ -742,9 +743,11 @@ private void withSearchExecutionContext(MapperService mapperService, CheckedCons
742743
743744 iw .addDocument (mapper .parse (source (b -> b .field ("field" , RARE_TOKENS ))).rootDoc ());
744745
745- // This will lower the averageTokenFreqRatio so that common tokens get pruned with default settings
746+ // This will lower the averageTokenFreqRatio so that common tokens get pruned with default settings.
747+ // Depending on how the index is created, we will have 30-37 numUniqueTokens
748+ // this will result in an averageTokenFreqRatio of 0.1021 - 0.1259
746749 Map <String , Float > uniqueDoc = new TreeMap <>();
747- for (int i = 0 ; i < 20 ; i ++) {
750+ for (int i = 0 ; i < 30 ; i ++) {
748751 uniqueDoc .put ("unique" + i , 0.5f );
749752 }
750753 iw .addDocument (mapper .parse (source (b -> b .field ("field" , uniqueDoc ))).rootDoc ());
@@ -758,10 +761,10 @@ private void withSearchExecutionContext(MapperService mapperService, CheckedCons
758761 }
759762
760763 public void testPruningScenarios () throws Exception {
761- for (int i = 0 ; i < 120 ; i ++) {
764+ for (int i = 0 ; i < 200 ; i ++) {
762765 assertPruningScenario (
763766 randomFrom (validIndexPruningScenarios ),
764- new PruningOptions (randomBoolean () ? randomBoolean () : null , randomFrom (PruningConfig .values ()))
767+ new PruningOptions (randomFrom ( true , false , null ) , randomFrom (PruningConfig .values ()))
765768 );
766769 }
767770 }
@@ -791,7 +794,8 @@ private PruningScenario getEffectivePruningScenario(
791794 }
792795
793796 if (shouldPrune == null ) {
794- shouldPrune = indexVersion .onOrAfter (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT );
797+ shouldPrune = indexVersion .between (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT_BACKPORT_8_X , UPGRADE_TO_LUCENE_10_0_0 )
798+ || indexVersion .onOrAfter (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT );
795799 }
796800
797801 PruningScenario pruningScenario = PruningScenario .NO_PRUNING ;
@@ -829,7 +833,7 @@ private List<Query> getExpectedQueryClauses(
829833 }
830834
831835 private void assertPruningScenario (PruningOptions indexPruningOptions , PruningOptions queryPruningOptions ) throws IOException {
832- IndexVersion indexVersion = getIndexVersionForTest ( randomBoolean () );
836+ IndexVersion indexVersion = getIndexVersion ( );
833837 MapperService mapperService = createMapperService (indexVersion , getIndexMapping (indexPruningOptions ));
834838 PruningScenario effectivePruningScenario = getEffectivePruningScenario (indexPruningOptions , queryPruningOptions , indexVersion );
835839 withSearchExecutionContext (mapperService , (context ) -> {
@@ -848,14 +852,41 @@ private void assertPruningScenario(PruningOptions indexPruningOptions, PruningOp
848852 });
849853 }
850854
851- private IndexVersion getIndexVersionForTest (boolean usePreviousIndex ) {
852- return usePreviousIndex
853- ? IndexVersionUtils .randomVersionBetween (
854- random (),
855- UPGRADE_TO_LUCENE_10_0_0 ,
856- IndexVersionUtils .getPreviousVersion (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT )
857- )
858- : IndexVersionUtils .randomVersionBetween (random (), SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT , IndexVersion .current ());
855+ private static IndexVersion getIndexVersion () {
856+ VersionRange versionRange = randomFrom (VersionRange .values ());
857+ return versionRange .getRandomVersion ();
858+ }
859+
860+ private enum VersionRange {
861+ ES_V8X_WITHOUT_INDEX_OPTIONS_SUPPORT (
862+ NEW_SPARSE_VECTOR ,
863+ IndexVersionUtils .getPreviousVersion (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT_BACKPORT_8_X )
864+ ),
865+ ES_V8X_WITH_INDEX_OPTIONS_SUPPORT (
866+ SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT_BACKPORT_8_X ,
867+ IndexVersionUtils .getPreviousVersion (UPGRADE_TO_LUCENE_10_0_0 )
868+ ),
869+ ES_V9X_WITHOUT_INDEX_OPTIONS_SUPPORT (
870+ UPGRADE_TO_LUCENE_10_0_0 ,
871+ IndexVersionUtils .getPreviousVersion (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT )
872+ ),
873+ ES_V9X_WITH_INDEX_OPTIONS_SUPPORT (SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT , IndexVersion .current ());
874+
875+ private final IndexVersion fromVersion ;
876+ private final IndexVersion toVersion ;
877+
878+ VersionRange (IndexVersion fromVersion , IndexVersion toVersion ) {
879+ this .fromVersion = fromVersion ;
880+ this .toVersion = toVersion ;
881+ }
882+
883+ IndexVersion getRandomVersion () {
884+ // TODO: replace implementation with `IndexVersionUtils::randomVersionBetween` once support is added
885+ // for handling unbalanced version distributions.
886+ NavigableSet <IndexVersion > allReleaseVersions = IndexVersionUtils .allReleasedVersions ();
887+ Set <IndexVersion > candidateVersions = allReleaseVersions .subSet (fromVersion , toVersion );
888+ return ESTestCase .randomFrom (candidateVersions );
889+ }
859890 }
860891
861892 private static final List <WeightedToken > QUERY_VECTORS = Stream .of (RARE_TOKENS , MEDIUM_TOKENS , COMMON_TOKENS )
0 commit comments