|
19 | 19 | import java.util.List; |
20 | 20 |
|
21 | 21 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; |
| 22 | +import static org.elasticsearch.xpack.esql.EsqlTestUtils.getValuesList; |
22 | 23 | import static org.hamcrest.CoreMatchers.containsString; |
| 24 | +import static org.hamcrest.Matchers.equalTo; |
| 25 | +import static org.hamcrest.Matchers.greaterThan; |
| 26 | +import static org.hamcrest.Matchers.lessThan; |
23 | 27 |
|
24 | 28 | //@TestLogging(value = "org.elasticsearch.xpack.esql:TRACE,org.elasticsearch.compute:TRACE", reason = "debug") |
25 | 29 | public class MatchFunctionIT extends AbstractEsqlIntegTestCase { |
@@ -260,6 +264,104 @@ public void testMatchWithinEval() { |
260 | 264 | assertThat(error.getMessage(), containsString("[MATCH] function is only supported in WHERE commands")); |
261 | 265 | } |
262 | 266 |
|
| 267 | + public void testDisjunctionScoring() { |
| 268 | + var query = """ |
| 269 | + FROM test METADATA _score |
| 270 | + | WHERE match(content, "fox") OR length(content) < 20 |
| 271 | + | KEEP id, _score |
| 272 | + | SORT _score DESC, id ASC |
| 273 | + """; |
| 274 | + |
| 275 | + try (var resp = run(query)) { |
| 276 | + assertColumnNames(resp.columns(), List.of("id", "_score")); |
| 277 | + assertColumnTypes(resp.columns(), List.of("integer", "double")); |
| 278 | + List<List<Object>> values = getValuesList(resp); |
| 279 | + assertThat(values.size(), equalTo(3)); |
| 280 | + |
| 281 | + assertThat(values.get(0).get(0), equalTo(1)); |
| 282 | + assertThat(values.get(1).get(0), equalTo(6)); |
| 283 | + assertThat(values.get(2).get(0), equalTo(2)); |
| 284 | + |
| 285 | + // Matches full text query and non pushable query |
| 286 | + assertThat((Double) values.get(0).get(1), greaterThan(1.0)); |
| 287 | + assertThat((Double) values.get(1).get(1), greaterThan(1.0)); |
| 288 | + // Matches just non pushable query |
| 289 | + assertThat((Double) values.get(2).get(1), equalTo(1.0)); |
| 290 | + } |
| 291 | + } |
| 292 | + |
| 293 | + public void testDisjunctionScoringMultipleNonPushableFunctions() { |
| 294 | + var query = """ |
| 295 | + FROM test METADATA _score |
| 296 | + | WHERE match(content, "fox") OR length(content) < 20 AND id > 2 |
| 297 | + | KEEP id, _score |
| 298 | + | SORT _score DESC |
| 299 | + """; |
| 300 | + |
| 301 | + try (var resp = run(query)) { |
| 302 | + assertColumnNames(resp.columns(), List.of("id", "_score")); |
| 303 | + assertColumnTypes(resp.columns(), List.of("integer", "double")); |
| 304 | + List<List<Object>> values = getValuesList(resp); |
| 305 | + assertThat(values.size(), equalTo(2)); |
| 306 | + |
| 307 | + assertThat(values.get(0).get(0), equalTo(1)); |
| 308 | + assertThat(values.get(1).get(0), equalTo(6)); |
| 309 | + |
| 310 | + // Matches the full text query and a two pushable query |
| 311 | + assertThat((Double) values.get(0).get(1), greaterThan(2.0)); |
| 312 | + assertThat((Double) values.get(0).get(1), lessThan(3.0)); |
| 313 | + // Matches just the match function |
| 314 | + assertThat((Double) values.get(1).get(1), lessThan(2.0)); |
| 315 | + assertThat((Double) values.get(1).get(1), greaterThan(1.0)); |
| 316 | + } |
| 317 | + } |
| 318 | + |
| 319 | + public void testDisjunctionScoringWithNot() { |
| 320 | + var query = """ |
| 321 | + FROM test METADATA _score |
| 322 | + | WHERE NOT(match(content, "dog")) OR length(content) > 50 |
| 323 | + | KEEP id, _score |
| 324 | + | SORT _score DESC, id ASC |
| 325 | + """; |
| 326 | + |
| 327 | + try (var resp = run(query)) { |
| 328 | + assertColumnNames(resp.columns(), List.of("id", "_score")); |
| 329 | + assertColumnTypes(resp.columns(), List.of("integer", "double")); |
| 330 | + List<List<Object>> values = getValuesList(resp); |
| 331 | + assertThat(values.size(), equalTo(3)); |
| 332 | + |
| 333 | + assertThat(values.get(0).get(0), equalTo(1)); |
| 334 | + assertThat(values.get(1).get(0), equalTo(4)); |
| 335 | + assertThat(values.get(2).get(0), equalTo(5)); |
| 336 | + |
| 337 | + // Matches NOT gets 0.0 and default score is 1.0 |
| 338 | + assertThat((Double) values.get(0).get(1), equalTo(1.0)); |
| 339 | + assertThat((Double) values.get(1).get(1), equalTo(1.0)); |
| 340 | + assertThat((Double) values.get(2).get(1), equalTo(1.0)); |
| 341 | + } |
| 342 | + } |
| 343 | + |
| 344 | + public void testScoringWithNoFullTextFunction() { |
| 345 | + var query = """ |
| 346 | + FROM test METADATA _score |
| 347 | + | WHERE length(content) > 50 |
| 348 | + | KEEP id, _score |
| 349 | + | SORT _score DESC, id ASC |
| 350 | + """; |
| 351 | + |
| 352 | + try (var resp = run(query)) { |
| 353 | + assertColumnNames(resp.columns(), List.of("id", "_score")); |
| 354 | + assertColumnTypes(resp.columns(), List.of("integer", "double")); |
| 355 | + List<List<Object>> values = getValuesList(resp); |
| 356 | + assertThat(values.size(), equalTo(1)); |
| 357 | + |
| 358 | + assertThat(values.get(0).get(0), equalTo(4)); |
| 359 | + |
| 360 | + // Non pushable query gets score of 0.0, summed with 1.0 coming from Lucene |
| 361 | + assertThat((Double) values.get(0).get(1), equalTo(1.0)); |
| 362 | + } |
| 363 | + } |
| 364 | + |
263 | 365 | private void createAndPopulateIndex() { |
264 | 366 | var indexName = "test"; |
265 | 367 | var client = client().admin().indices(); |
|
0 commit comments