Skip to content

Commit 72ad55f

Browse files
Merge branch 'main' into 238-add-note
2 parents b48e244 + 94648e4 commit 72ad55f

File tree

5 files changed

+63
-6
lines changed

5 files changed

+63
-6
lines changed

docs/changelog/133357.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pr: 133357
2+
summary: Switch to Sending a Bad Request User When Function Score Query Generates
3+
Negative Scores
4+
area: Search
5+
type: bug
6+
issues:
7+
- 133358

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/610_function_score.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,47 @@
138138
}
139139
- length: { hits.hits: 2 }
140140
- match: { hits.total.value: 2 }
141+
142+
---
143+
"formulating a function score query with a negative number returns bad request":
144+
- requires:
145+
cluster_features: [ "search.negative.function.score.bad.request" ]
146+
reason: "Testing the behaviour change with this feature"
147+
- do:
148+
indices.create:
149+
index: test
150+
body:
151+
settings:
152+
number_of_shards: 1
153+
number_of_replicas: 1
154+
mappings:
155+
properties:
156+
qty:
157+
type: float
158+
- do:
159+
index:
160+
index: test
161+
id: "1"
162+
body: { qty: -1, uuid: 3456 }
163+
- do:
164+
indices.refresh: {}
165+
- do:
166+
catch: bad_request
167+
search:
168+
index: test
169+
body:
170+
query:
171+
"function_score": {
172+
"query": {
173+
"match_all": {}
174+
},
175+
"field_value_factor": {
176+
"field": "qty",
177+
"factor": 1.2,
178+
"missing": 1,
179+
"modifier": "ln1p"
180+
}
181+
}
182+
- match: { status: 400 }
183+
- match: { error.root_cause.0.type: "illegal_argument_exception" }
184+
- match: { error.root_cause.0.reason: "function score query returned an invalid score: NaN for doc: 0; score must be a non-negative real number" }

server/src/main/java/org/elasticsearch/common/lucene/search/function/FunctionScoreQuery.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.apache.lucene.search.ScorerSupplier;
2222
import org.apache.lucene.search.Weight;
2323
import org.apache.lucene.util.Bits;
24-
import org.elasticsearch.ElasticsearchException;
2524
import org.elasticsearch.common.io.stream.StreamInput;
2625
import org.elasticsearch.common.io.stream.StreamOutput;
2726
import org.elasticsearch.common.io.stream.Writeable;
@@ -448,7 +447,13 @@ public float score() throws IOException {
448447
These scores are invalid for score based {@link org.apache.lucene.search.TopDocsCollector}s.
449448
See {@link org.apache.lucene.search.TopScoreDocCollector} for details.
450449
*/
451-
throw new ElasticsearchException("function score query returned an invalid score: " + finalScore + " for doc: " + docId);
450+
throw new IllegalArgumentException(
451+
"function score query returned an invalid score: "
452+
+ finalScore
453+
+ " for doc: "
454+
+ docId
455+
+ "; score must be a non-negative real number"
456+
);
452457
}
453458
return finalScore;
454459
}

server/src/main/java/org/elasticsearch/search/SearchFeatures.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public Set<NodeFeature> getFeatures() {
3434
public static final NodeFeature BBQ_HNSW_DEFAULT_INDEXING = new NodeFeature("search.vectors.mappers.default_bbq_hnsw");
3535
public static final NodeFeature SEARCH_WITH_NO_DIMENSIONS_BUGFIX = new NodeFeature("search.vectors.no_dimensions_bugfix");
3636
public static final NodeFeature SEARCH_RESCORE_SCRIPT = new NodeFeature("search.rescore.script");
37+
public static final NodeFeature NEGATIVE_FUNCTION_SCORE_BAD_REQUEST = new NodeFeature("search.negative.function.score.bad.request");
3738

3839
@Override
3940
public Set<NodeFeature> getTestFeatures() {
@@ -45,7 +46,8 @@ public Set<NodeFeature> getTestFeatures() {
4546
MULTI_MATCH_CHECKS_POSITIONS,
4647
BBQ_HNSW_DEFAULT_INDEXING,
4748
SEARCH_WITH_NO_DIMENSIONS_BUGFIX,
48-
SEARCH_RESCORE_SCRIPT
49+
SEARCH_RESCORE_SCRIPT,
50+
NEGATIVE_FUNCTION_SCORE_BAD_REQUEST
4951
);
5052
}
5153
}

server/src/test/java/org/elasticsearch/index/query/functionscore/FunctionScoreTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import org.apache.lucene.tests.search.RandomApproximationQuery;
3232
import org.apache.lucene.util.Accountable;
3333
import org.apache.lucene.util.BytesRef;
34-
import org.elasticsearch.ElasticsearchException;
3534
import org.elasticsearch.common.lucene.search.function.CombineFunction;
3635
import org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction;
3736
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
@@ -944,7 +943,7 @@ public void testWithInvalidScores() {
944943
null,
945944
Float.POSITIVE_INFINITY
946945
);
947-
ElasticsearchException exc = expectThrows(ElasticsearchException.class, () -> localSearcher.search(query1, 1));
946+
IllegalArgumentException exc = expectThrows(IllegalArgumentException.class, () -> localSearcher.search(query1, 1));
948947
assertThat(exc.getMessage(), containsString("function score query returned an invalid score: " + Float.NaN));
949948
FunctionScoreQuery query2 = new FunctionScoreQuery(
950949
new TermQuery(new Term(FIELD, "out")),
@@ -953,7 +952,7 @@ public void testWithInvalidScores() {
953952
null,
954953
Float.POSITIVE_INFINITY
955954
);
956-
exc = expectThrows(ElasticsearchException.class, () -> localSearcher.search(query2, 1));
955+
exc = expectThrows(IllegalArgumentException.class, () -> localSearcher.search(query2, 1));
957956
assertThat(exc.getMessage(), containsString("function score query returned an invalid score: " + Float.NEGATIVE_INFINITY));
958957
}
959958

0 commit comments

Comments
 (0)