Skip to content

Commit

Permalink
KnnVectorQueryBuilder support for allowUnmappedFields (elastic#107047)
Browse files Browse the repository at this point in the history
* KnnVectorQueryBuilder  support for allowUnmappedFields

* Update and rename 106811.yaml to 107047.yaml

* Update 107047.yaml

* buildkite test

* spotless

* spotless

* Apply suggestions from code review

* fixing compilation

---------

Co-authored-by: Benjamin Trent <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: Benjamin Trent <[email protected]>
  • Loading branch information
4 people authored Jul 10, 2024
1 parent 2901711 commit 3bd192c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 3 deletions.
6 changes: 6 additions & 0 deletions docs/changelog/107047.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 107047
summary: "Search/Mapping: KnnVectorQueryBuilder support for allowUnmappedFields"
area: Search
type: bug
issues:
- 106846
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ setup:
- requires:
cluster_features: "gte_v8.4.0"
reason: 'kNN added to search endpoint in 8.4'
- skip:
cluster_features: "gte_v8.16.0"
reason: 'non-existent field handling improved in 8.16'
- do:
catch: bad_request
search:
Expand All @@ -298,9 +301,28 @@ setup:
query_vector: [ -0.5, 90.0, -10, 14.8, -156.0 ]
k: 2
num_candidates: 3

- match: { error.root_cause.0.type: "query_shard_exception" }
- match: { error.root_cause.0.reason: "failed to create query: field [nonexistent] does not exist in the mapping" }

---
"Test nonexistent field is match none":
- requires:
cluster_features: "gte_v8.16.0"
reason: 'non-existent field handling improved in 8.16'
- do:
search:
index: test
body:
fields: [ "name" ]
knn:
field: nonexistent
query_vector: [ -0.5, 90.0, -10, 14.8, -156.0 ]
k: 2
num_candidates: 3

- length: {hits.hits: 0}

---
"KNN Vector similarity search only":
- requires:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ setup:

---
"Test nonexistent field":
- skip:
cluster_features: 'gte_v8.16.0'
reason: 'non-existent field handling improved in 8.16'
- do:
catch: bad_request
search:
Expand All @@ -159,8 +162,26 @@ setup:
query_vector: [ 1, 0, 0, 0, -1 ]
k: 2
num_candidates: 3

- match: { error.root_cause.0.type: "query_shard_exception" }
- match: { error.root_cause.0.reason: "failed to create query: field [nonexistent] does not exist in the mapping" }
---
"Test nonexistent field is match none":
- requires:
cluster_features: 'gte_v8.16.0'
reason: 'non-existent field handling improved in 8.16'
- do:
search:
index: test
body:
fields: [ "name" ]
knn:
field: nonexistent
query_vector: [ 1, 0, 0, 0, -1 ]
k: 2
num_candidates: 3

- length: {hits.hits: 0}

---
"Vector similarity search only":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.join.BitSetProducer;
import org.apache.lucene.search.join.ToChildBlockJoinQuery;
Expand Down Expand Up @@ -436,7 +437,7 @@ protected Query doToQuery(SearchExecutionContext context) throws IOException {
? Math.round(Math.min(NUM_CANDS_MULTIPLICATIVE_FACTOR * requestSize, NUM_CANDS_LIMIT))
: numCands;
if (fieldType == null) {
throw new IllegalArgumentException("field [" + fieldName + "] does not exist in the mapping");
return new MatchNoDocsQuery();
}

if (fieldType instanceof DenseVectorFieldType == false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.TransportVersion;
import org.elasticsearch.TransportVersions;
Expand All @@ -25,6 +26,7 @@
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryRewriteContext;
import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.index.query.Rewriteable;
import org.elasticsearch.index.query.SearchExecutionContext;
import org.elasticsearch.index.query.TermQueryBuilder;
Expand Down Expand Up @@ -157,8 +159,16 @@ public void testWrongDimension() {
public void testNonexistentField() {
SearchExecutionContext context = createSearchExecutionContext();
KnnVectorQueryBuilder query = new KnnVectorQueryBuilder("nonexistent", new float[] { 1.0f, 1.0f, 1.0f }, 5, 10, null);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> query.doToQuery(context));
assertThat(e.getMessage(), containsString("field [nonexistent] does not exist in the mapping"));
context.setAllowUnmappedFields(false);
QueryShardException e = expectThrows(QueryShardException.class, () -> query.doToQuery(context));
assertThat(e.getMessage(), containsString("No field mapping can be found for the field with name [nonexistent]"));
}

public void testNonexistentFieldReturnEmpty() throws IOException {
SearchExecutionContext context = createSearchExecutionContext();
KnnVectorQueryBuilder query = new KnnVectorQueryBuilder("nonexistent", new float[] { 1.0f, 1.0f, 1.0f }, 5, 10, null);
Query queryNone = query.doToQuery(context);
assertThat(queryNone, instanceOf(MatchNoDocsQuery.class));
}

public void testWrongFieldType() {
Expand Down

0 comments on commit 3bd192c

Please sign in to comment.