diff --git a/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java b/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java index 1ec3fcbc6..fa4019640 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java @@ -1426,6 +1426,7 @@ class RequestConverter extends AbstractQueryProcessor { .searchType(searchType) // .timeout(timeStringMs(query.getTimeout())) // .requestCache(query.getRequestCache()) // + .includeNamedQueriesScore(query.getIncludeNamedQueriesScore()) // ; var pointInTime = query.getPointInTime(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQuery.java index 611e59f61..1137f5bb2 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQuery.java @@ -81,6 +81,7 @@ public class BaseQuery implements Query { protected List idsWithRouting = Collections.emptyList(); protected List runtimeFields = new ArrayList<>(); @Nullable protected PointInTime pointInTime; + @Nullable protected Boolean includeNamedQueriesScore; private boolean queryIsUpdatedByConverter = false; @Nullable private Integer reactiveBatchSize = null; @Nullable private Boolean allowNoIndices = null; @@ -123,6 +124,7 @@ public class BaseQuery implements Query { this.docValueFields = builder.getDocValueFields(); this.scriptedFields = builder.getScriptedFields(); this.runtimeFields = builder.getRuntimeFields(); + this.includeNamedQueriesScore = builder.getIncludeNamedQueriesScore(); } /** @@ -455,6 +457,11 @@ public class BaseQuery implements Query { this.requestCache = value; } + @Override + public void setIncludeNamedQueriesScore(@Nullable Boolean value) { + this.includeNamedQueriesScore = value; + } + @Override @Nullable public Boolean getRequestCache() { @@ -480,6 +487,11 @@ public class BaseQuery implements Query { return indicesBoost; } + @Override + public @Nullable Boolean getIncludeNamedQueriesScore() { + return this.includeNamedQueriesScore; + } + /** * @since 5.0 */ diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQueryBuilder.java index 7aa35b6ad..77cb62f28 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/BaseQueryBuilder.java @@ -71,6 +71,7 @@ public abstract class BaseQueryBuilder docValueFields = new ArrayList<>(); private final List scriptedFields = new ArrayList<>(); + @Nullable private Boolean includeNamedQueryScore; @Nullable public Sort getSort() { @@ -177,6 +178,11 @@ public abstract class BaseQueryBuilder getIdsWithRouting() { return idsWithRouting; } @@ -381,6 +387,11 @@ public abstract class BaseQueryBuilder m.field("text") + .query("matched") + .queryName("namedQuery")); + + var nativeQuery = NativeQuery.builder() + .withQuery(matchQuery._toQuery()) + .withIncludeNamedQueryScore(true) + .build(); + + var searchHits = operations.search(nativeQuery, SampleEntity.class); + + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getId()).isEqualTo(entity.getId()); + assertThat(searchHits.getSearchHit(0).getMatchedQueries()).containsKey("namedQuery"); + assertThat(searchHits.getSearchHit(0).getMatchedQueries().get("namedQuery")).isGreaterThan(0.0); + assertThat(searchHits.getSearchHit(0).getMatchedQueries().get("namedQuery")) + .isCloseTo(searchHits.getMaxScore(), Offset.offset(0.01)); + } + + @Test // #3248 + @DisplayName("should not be able to use named queries score in a NativeQuery when disabled") + void shouldNotBeAbleToUseNamedQueriesScoreInANativeQueryWhenDisabled() { + + var entity = new SampleEntity(); + entity.setId("7"); + entity.setText("seven"); + operations.save(entity); + entity = new SampleEntity(); + entity.setId("42"); + entity.setText("matched"); + operations.save(entity); + + var matchQuery = MatchQuery.of(m -> m.field("text") + .query("matched") + .queryName("namedQuery")); + + var nativeQuery = NativeQuery.builder() + .withQuery(matchQuery._toQuery()) + .withIncludeNamedQueryScore(false) + .build(); + + var searchHits = operations.search(nativeQuery, SampleEntity.class); + + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getId()).isEqualTo(entity.getId()); + assertThat(searchHits.getSearchHit(0).getMatchedQueries()).containsKey("namedQuery"); + assertThat(searchHits.getSearchHit(0).getMatchedQueries().get("namedQuery")).isNull(); + } + @Document(indexName = "#{@indexNameProvider.indexName()}") static class SampleEntity {