|
27 | 27 | import java.util.Map; |
28 | 28 |
|
29 | 29 | import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; |
| 30 | +import static org.elasticsearch.xpack.esql.EsqlTestUtils.getValuesList; |
30 | 31 | import static org.hamcrest.Matchers.equalTo; |
| 32 | +import static org.hamcrest.Matchers.greaterThan; |
| 33 | +import static org.hamcrest.Matchers.lessThan; |
31 | 34 |
|
32 | 35 | public class ScoringIT extends AbstractEsqlIntegTestCase { |
33 | 36 |
|
@@ -186,8 +189,6 @@ public void testPushableFunctionsScoring() { |
186 | 189 |
|
187 | 190 | private void assertZeroScore(String query) { |
188 | 191 | try (var resp = run(query)) { |
189 | | - assertColumnNames(resp.columns(), List.of("id", "_score")); |
190 | | - assertColumnTypes(resp.columns(), List.of("integer", "double")); |
191 | 192 | List<List<Object>> values = EsqlTestUtils.getValuesList(resp.values()); |
192 | 193 | for (List<Object> value : values) { |
193 | 194 | assertThat((Double) value.get(1), equalTo(0.0)); |
@@ -229,6 +230,112 @@ public void testPushableAndFullTextFunctionsConjunctionScoring() { |
229 | 230 | checkSameScores(queryWithoutFilter, query); |
230 | 231 | } |
231 | 232 |
|
| 233 | + public void testDisjunctionScoring() { |
| 234 | + var queryWithoutFilter = String.format(Locale.ROOT, """ |
| 235 | + FROM test |
| 236 | + METADATA _score |
| 237 | + | WHERE %s OR length(content) < 20 |
| 238 | + | KEEP id, _score |
| 239 | + | SORT _score DESC, id ASC |
| 240 | + """, matchingClause); |
| 241 | + var query = String.format(Locale.ROOT, """ |
| 242 | + FROM test |
| 243 | + METADATA _score |
| 244 | + | WHERE %s |
| 245 | + | KEEP id, _score |
| 246 | + | SORT _score DESC, id ASC |
| 247 | + """, matchingClause); |
| 248 | + |
| 249 | + checkSameScores(queryWithoutFilter, query); |
| 250 | + |
| 251 | + try (var resp = run(queryWithoutFilter)) { |
| 252 | + List<List<Object>> values = getValuesList(resp); |
| 253 | + assertThat(values.size(), equalTo(3)); |
| 254 | + |
| 255 | + assertThat(values.get(0).get(0), equalTo(1)); |
| 256 | + assertThat(values.get(1).get(0), equalTo(6)); |
| 257 | + assertThat(values.get(2).get(0), equalTo(2)); |
| 258 | + |
| 259 | + // Matches full text query and non pushable query |
| 260 | + assertThat((Double) values.get(0).get(1), greaterThan(0.0)); |
| 261 | + assertThat((Double) values.get(1).get(1), greaterThan(0.0)); |
| 262 | + // Matches just non pushable query |
| 263 | + assertThat((Double) values.get(2).get(1), equalTo(0.0)); |
| 264 | + } |
| 265 | + } |
| 266 | + |
| 267 | + public void testDisjunctionScoringPushableFunctions() { |
| 268 | + var query = String.format(Locale.ROOT, """ |
| 269 | + FROM test METADATA _score |
| 270 | + | WHERE %s OR match(content, "quick") |
| 271 | + | KEEP id, _score |
| 272 | + | SORT _score DESC, id ASC |
| 273 | + """, matchingClause); |
| 274 | + |
| 275 | + try (var resp = run(query)) { |
| 276 | + List<List<Object>> values = getValuesList(resp); |
| 277 | + assertThat(values.size(), equalTo(2)); |
| 278 | + |
| 279 | + assertThat(values.get(0).get(0), equalTo(6)); |
| 280 | + assertThat(values.get(1).get(0), equalTo(1)); |
| 281 | + |
| 282 | + // Matches both conditions |
| 283 | + assertThat((Double) values.get(0).get(1), greaterThan(2.0)); |
| 284 | + // Matches a single condition |
| 285 | + assertThat((Double) values.get(1).get(1), greaterThan(1.0)); |
| 286 | + } |
| 287 | + } |
| 288 | + |
| 289 | + public void testDisjunctionScoringMultipleNonPushableFunctions() { |
| 290 | + var query = String.format(Locale.ROOT, """ |
| 291 | + FROM test METADATA _score |
| 292 | + | WHERE %s |
| 293 | + | KEEP id, _score |
| 294 | + | SORT _score DESC |
| 295 | + """, matchingClause); |
| 296 | + var queryWithoutFilter = String.format(Locale.ROOT, """ |
| 297 | + FROM test METADATA _score |
| 298 | + | WHERE %s OR length(content) < 20 AND id > 2 |
| 299 | + | KEEP id, _score |
| 300 | + | SORT _score DESC |
| 301 | + """, matchingClause); |
| 302 | + |
| 303 | + checkSameScores(queryWithoutFilter, query); |
| 304 | + |
| 305 | + try (var resp = run(queryWithoutFilter)) { |
| 306 | + List<List<Object>> values = getValuesList(resp); |
| 307 | + assertThat(values.size(), equalTo(2)); |
| 308 | + |
| 309 | + assertThat(values.get(0).get(0), equalTo(1)); |
| 310 | + assertThat(values.get(1).get(0), equalTo(6)); |
| 311 | + |
| 312 | + // Matches the full text query and the two pushable query |
| 313 | + assertThat((Double) values.get(0).get(1), greaterThan(0.0)); |
| 314 | + // Matches just the match function |
| 315 | + assertThat((Double) values.get(1).get(1), lessThan(1.0)); |
| 316 | + assertThat((Double) values.get(1).get(1), greaterThan(0.1)); |
| 317 | + } |
| 318 | + } |
| 319 | + |
| 320 | + public void testDisjunctionScoringWithNot() { |
| 321 | + var query = String.format(Locale.ROOT, """ |
| 322 | + FROM test METADATA _score |
| 323 | + | WHERE NOT(%s) OR length(content) > 50 |
| 324 | + | KEEP id, _score |
| 325 | + | SORT _score DESC, id ASC |
| 326 | + """, matchingClause); |
| 327 | + |
| 328 | + try (var resp = run(query)) { |
| 329 | + // Matches NOT gets 0.0 |
| 330 | + assertThat(getValuesList(resp), equalTo(List.of( |
| 331 | + List.of(2, 0.0), |
| 332 | + List.of(3, 0.0), |
| 333 | + List.of(4, 0.0), |
| 334 | + List.of(5, 0.0) |
| 335 | + ))); |
| 336 | + } |
| 337 | + } |
| 338 | + |
232 | 339 | private void checkSameScores(String queryWithoutFilter, String query) { |
233 | 340 | Map<Integer, Double> expectedScores = new HashMap<>(); |
234 | 341 | try (var respWithoutFilter = run(queryWithoutFilter)) { |
|
0 commit comments