Skip to content

Commit c0704df

Browse files
committed
clean SparseVectorQueryBuilderTests
1 parent 88fc1f4 commit c0704df

File tree

2 files changed

+96
-125
lines changed

2 files changed

+96
-125
lines changed

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilderTests.java

Lines changed: 39 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@
4444
import org.elasticsearch.xpack.core.ml.inference.results.TextExpansionResults;
4545

4646
import java.io.IOException;
47-
import java.lang.annotation.ElementType;
48-
import java.lang.annotation.Retention;
49-
import java.lang.annotation.RetentionPolicy;
50-
import java.lang.annotation.Target;
5147
import java.lang.reflect.Method;
5248
import java.util.ArrayList;
5349
import java.util.Collection;
@@ -65,17 +61,20 @@ public class SparseVectorQueryBuilderTests extends AbstractQueryTestCase<SparseV
6561
private static final int NUM_TOKENS = WEIGHTED_TOKENS.size();
6662
private final IndexVersion indexVersionToTest;
6763

68-
@Retention(RetentionPolicy.RUNTIME)
69-
@Target(ElementType.METHOD)
70-
public @interface InjectSparseVectorIndexOptions {
71-
}
72-
7364
public SparseVectorQueryBuilderTests() {
7465
// The sparse_vector field is not supported on versions 8.0 to 8.10. Because of this we'll only allow
7566
// index versions after its reintroduction.
7667
indexVersionToTest = randomBoolean()
77-
? IndexVersion.current()
78-
: IndexVersionUtils.randomVersionBetween(random(), IndexVersions.NEW_SPARSE_VECTOR, IndexVersion.current());
68+
? IndexVersionUtils.randomVersionBetween(
69+
random(),
70+
IndexVersions.SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT,
71+
IndexVersion.current()
72+
)
73+
: IndexVersionUtils.randomVersionBetween(
74+
random(),
75+
IndexVersions.NEW_SPARSE_VECTOR,
76+
IndexVersions.SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT
77+
);
7978
}
8079

8180
@Override
@@ -159,50 +158,8 @@ protected Object simulateMethod(Method method, Object[] args) {
159158

160159
@Override
161160
protected void initializeAdditionalMappings(MapperService mapperService) throws IOException {
162-
mapperService.merge("_doc", new CompressedXContent(getTestSparseVectorIndexMapping()), MapperService.MergeReason.MAPPING_UPDATE);
163-
}
164-
165-
private String getTestSparseVectorIndexMapping() {
166-
if (currentTestHasIndexOptions()) {
167-
return "{\"properties\":{\""
168-
+ SPARSE_VECTOR_FIELD
169-
+ "\":{\"type\":\"sparse_vector\",\"index_options\""
170-
+ ":{\"prune\":true,\"pruning_config\":{\"tokens_freq_ratio_threshold\""
171-
+ ":12,\"tokens_weight_threshold\":0.6}}}}}";
172-
}
173-
174-
return Strings.toString(PutMappingRequest.simpleMapping(SPARSE_VECTOR_FIELD, "type=sparse_vector"));
175-
}
176-
177-
private boolean currentTestHasIndexOptions() {
178-
if (indexVersionSupportsIndexOptions() == false) {
179-
return false;
180-
}
181-
182-
Class<?> clazz = this.getClass();
183-
Class<InjectSparseVectorIndexOptions> injectSparseVectorIndexOptions = InjectSparseVectorIndexOptions.class;
184-
185-
try {
186-
Method method = clazz.getMethod(this.getTestName());
187-
return method.isAnnotationPresent(injectSparseVectorIndexOptions);
188-
} catch (NoSuchMethodException e) {
189-
return false;
190-
}
191-
}
192-
193-
private boolean indexVersionSupportsIndexOptions() {
194-
if (indexVersionToTest.onOrAfter(IndexVersions.SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT)) {
195-
return true;
196-
}
197-
198-
if (indexVersionToTest.between(
199-
IndexVersions.SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT_BACKPORT_8_X,
200-
IndexVersions.UPGRADE_TO_LUCENE_10_0_0
201-
)) {
202-
return true;
203-
}
204-
205-
return false;
161+
String mapping = Strings.toString(PutMappingRequest.simpleMapping(SPARSE_VECTOR_FIELD, "type=sparse_vector"));
162+
mapperService.merge("_doc", new CompressedXContent(mapping), MapperService.MergeReason.MAPPING_UPDATE);
206163
}
207164

208165
@Override
@@ -242,15 +199,11 @@ private void withSearchIndex(CheckedConsumer<SearchExecutionContext, IOException
242199
@Override
243200
public void testCacheability() throws IOException {
244201
withSearchIndex((context) -> {
245-
try {
246-
SparseVectorQueryBuilder queryBuilder = createTestQueryBuilder();
247-
QueryBuilder rewriteQuery = null;
248-
rewriteQuery = rewriteQuery(queryBuilder, new SearchExecutionContext(context));
249-
assertNotNull(rewriteQuery.toQuery(context));
250-
assertTrue("query should be cacheable: " + queryBuilder.toString(), context.isCacheable());
251-
} catch (IOException e) {
252-
throw new RuntimeException(e);
253-
}
202+
SparseVectorQueryBuilder queryBuilder = createTestQueryBuilder();
203+
QueryBuilder rewriteQuery = null;
204+
rewriteQuery = rewriteQuery(queryBuilder, new SearchExecutionContext(context));
205+
assertNotNull(rewriteQuery.toQuery(context));
206+
assertTrue("query should be cacheable: " + queryBuilder.toString(), context.isCacheable());
254207
});
255208
}
256209

@@ -260,12 +213,8 @@ public void testCacheability() throws IOException {
260213
@Override
261214
public void testMustRewrite() throws IOException {
262215
withSearchIndex((context) -> {
263-
try {
264-
SparseVectorQueryBuilder queryBuilder = createTestQueryBuilder();
265-
queryBuilder.toQuery(context);
266-
} catch (IOException e) {
267-
throw new RuntimeException(e);
268-
}
216+
SparseVectorQueryBuilder queryBuilder = createTestQueryBuilder();
217+
queryBuilder.toQuery(context);
269218
});
270219
}
271220

@@ -275,17 +224,13 @@ public void testMustRewrite() throws IOException {
275224
@Override
276225
public void testToQuery() throws IOException {
277226
withSearchIndex((context) -> {
278-
try {
279-
SparseVectorQueryBuilder queryBuilder = createTestQueryBuilder();
280-
if (queryBuilder.getQueryVectors() == null) {
281-
QueryBuilder rewrittenQueryBuilder = rewriteAndFetch(queryBuilder, context);
282-
assertTrue(rewrittenQueryBuilder instanceof SparseVectorQueryBuilder);
283-
testDoToQuery((SparseVectorQueryBuilder) rewrittenQueryBuilder, context);
284-
} else {
285-
testDoToQuery(queryBuilder, context);
286-
}
287-
} catch (IOException e) {
288-
throw new RuntimeException(e);
227+
SparseVectorQueryBuilder queryBuilder = createTestQueryBuilder();
228+
if (queryBuilder.getQueryVectors() == null) {
229+
QueryBuilder rewrittenQueryBuilder = rewriteAndFetch(queryBuilder, context);
230+
assertTrue(rewrittenQueryBuilder instanceof SparseVectorQueryBuilder);
231+
testDoToQuery((SparseVectorQueryBuilder) rewrittenQueryBuilder, context);
232+
} else {
233+
testDoToQuery(queryBuilder, context);
289234
}
290235
});
291236
}
@@ -301,8 +246,8 @@ private void testDoToQuery(SparseVectorQueryBuilder queryBuilder, SearchExecutio
301246
assertTrue(query instanceof SparseVectorQueryWrapper);
302247
var sparseQuery = (SparseVectorQueryWrapper) query;
303248

304-
// check if we have explicit pruning, or pruning via the index_options
305-
if (queryBuilder.shouldPruneTokens() || currentTestHasIndexOptions()) {
249+
// check if we have explicit pruning or implicit pruning=true
250+
if (queryBuilder.shouldPruneTokens() || indexVersionSupportsIndexOptions()) {
306251
// It's possible that all documents were pruned for aggressive pruning configurations
307252
assertTrue(sparseQuery.getTermsQuery() instanceof BooleanQuery || sparseQuery.getTermsQuery() instanceof MatchNoDocsQuery);
308253
} else {
@@ -401,48 +346,18 @@ public void testThatWeCorrectlyRewriteQueryIntoVectors() {
401346
assertNotNull(((SparseVectorQueryBuilder) rewrittenQueryBuilder).getQueryVectors());
402347
}
403348

404-
@InjectSparseVectorIndexOptions
405-
public void testItUsesIndexOptionsDefaults() throws IOException {
406-
withSearchIndex((context) -> {
407-
try {
408-
SparseVectorQueryBuilder builder = createTestQueryBuilder(null);
409-
assertFalse(builder.shouldPruneTokens());
410-
testDoToQuery(builder, context);
411-
} catch (IOException ex) {
412-
throw new RuntimeException(ex);
413-
}
414-
});
415-
}
349+
private boolean indexVersionSupportsIndexOptions() {
350+
if (indexVersionToTest.onOrAfter(IndexVersions.SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT)) {
351+
return true;
352+
}
416353

417-
@InjectSparseVectorIndexOptions
418-
public void testItOverridesIndexOptionsDefaults() throws IOException {
419-
withSearchIndex((context) -> {
420-
try {
421-
TokenPruningConfig pruningConfig = new TokenPruningConfig(2, 0.3f, false);
422-
SparseVectorQueryBuilder builder = createTestQueryBuilder(pruningConfig);
423-
assertTrue(builder.shouldPruneTokens());
424-
testDoToQuery(builder, context);
425-
} catch (IOException ex) {
426-
throw new RuntimeException(ex);
427-
}
428-
});
429-
}
354+
if (indexVersionToTest.between(
355+
IndexVersions.SPARSE_VECTOR_PRUNING_INDEX_OPTIONS_SUPPORT_BACKPORT_8_X,
356+
IndexVersions.UPGRADE_TO_LUCENE_10_0_0
357+
)) {
358+
return true;
359+
}
430360

431-
@InjectSparseVectorIndexOptions
432-
public void testToQueryRewriteWithIndexOptions() throws IOException {
433-
withSearchIndex((context) -> {
434-
SparseVectorQueryBuilder queryBuilder = createTestQueryBuilder(null);
435-
try {
436-
if (queryBuilder.getQueryVectors() == null) {
437-
QueryBuilder rewrittenQueryBuilder = rewriteAndFetch(queryBuilder, context);
438-
assertTrue(rewrittenQueryBuilder instanceof SparseVectorQueryBuilder);
439-
testDoToQuery((SparseVectorQueryBuilder) rewrittenQueryBuilder, context);
440-
} else {
441-
testDoToQuery(queryBuilder, context);
442-
}
443-
} catch (IOException e) {
444-
throw new RuntimeException(e);
445-
}
446-
});
361+
return false;
447362
}
448363
}

x-pack/plugin/ml/qa/multi-cluster-tests-with-security/src/test/resources/rest-api-spec/test/multi_cluster/50_sparse_vector.yml

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ teardown:
273273
index: sparse_vector_pruning_test
274274

275275
- not_exists: sparse_vector_pruning_test.mappings.properties.ml.properties.tokens.index_options
276-
- not_exists: sparse_vector_pruning_test.mappings.properties.embeddings.index_options
277276

278277
---
279278
"Check sparse_vector token pruning index_options prune missing do not allow config":
@@ -554,3 +553,60 @@ teardown:
554553
- match: { hits.hits.0._id: "1" }
555554
- match: { hits.hits.1._id: "3" }
556555
- match: { hits.hits.2._id: "2" }
556+
557+
---
558+
"Check sparse_vector should prune by default":
559+
560+
- requires:
561+
cluster_features: 'sparse_vector.index_options_supported'
562+
reason: "sparse_vector token pruning index options added support in 8.19"
563+
- skip:
564+
features: headers
565+
566+
- do:
567+
headers:
568+
Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" #test_user credentials
569+
Content-Type: application/json
570+
indices.create:
571+
index: test-sparse-vector-pruning-default
572+
body:
573+
mappings:
574+
properties:
575+
content_embedding:
576+
type: sparse_vector
577+
578+
- match: { acknowledged: true }
579+
580+
- do:
581+
headers:
582+
Authorization: "Basic dGVzdF91c2VyOngtcGFjay10ZXN0LXBhc3N3b3Jk" #test_user credentials
583+
Content-Type: application/json
584+
bulk:
585+
index: test-sparse-vector-pruning-default
586+
refresh: true
587+
body: |
588+
{"index": { "_id": "1" }}
589+
{"content_embedding":{"cheese": 2.671405,"is": 0.11809908,"comet": 0.26088917}}
590+
{"index": { "_id": "2" }}
591+
{"content_embedding":{"planet": 2.3438394,"is": 0.54600334,"astronomy": 0.36015007,"moon": 0.20022368}}
592+
{"index": { "_id": "3" }}
593+
{"content_embedding":{"is": 0.6891394,"globe": 0.484035,"ocean": 0.080102935,"underground": 0.053516876}}
594+
595+
- do:
596+
search:
597+
index: test-sparse-vector-pruning-default
598+
body:
599+
query:
600+
sparse_vector:
601+
field: content_embedding
602+
query_vector:
603+
cheese: 0.5
604+
comet: 0.5
605+
globe: 0.484035
606+
ocean: 0.080102935
607+
underground: 0.053516876
608+
is: 0.54600334
609+
610+
- match: { hits.total.value: 2 }
611+
- match: { hits.hits.0._id: "1" }
612+
- match: { hits.hits.1._id: "3" }

0 commit comments

Comments
 (0)