Skip to content

Commit 2c85717

Browse files
committed
Fix reactive native sort.
Original Pull Request #2746 Closes #2745 (cherry picked from commit 73fe086)
1 parent f087d5a commit 2c85717

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

src/main/java/org/springframework/data/elasticsearch/client/elc/RequestConverter.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -1341,14 +1341,6 @@ private <T> void prepareSearchRequest(Query query, @Nullable String routing, @Nu
13411341
builder.minScore((double) query.getMinScore());
13421342
}
13431343

1344-
if (query.getSort() != null) {
1345-
List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity);
1346-
1347-
if (!sortOptions.isEmpty()) {
1348-
builder.sort(sortOptions);
1349-
}
1350-
}
1351-
13521344
addHighlight(query, builder);
13531345

13541346
query.getScriptedFields().forEach(scriptedField -> builder.scriptFields(scriptedField.getFieldName(),
@@ -1357,6 +1349,15 @@ private <T> void prepareSearchRequest(Query query, @Nullable String routing, @Nu
13571349
if (query instanceof NativeQuery) {
13581350
prepareNativeSearch((NativeQuery) query, builder);
13591351
}
1352+
// query.getSort() must be checked after prepareNativeSearch as this already might hav a sort set that must have
1353+
// higher priority
1354+
if (query.getSort() != null) {
1355+
List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity);
1356+
1357+
if (!sortOptions.isEmpty()) {
1358+
builder.sort(sortOptions);
1359+
}
1360+
}
13601361

13611362
if (query.getTrackTotalHits() != null) {
13621363
// logic from the RHLC, choose between -1 and Integer.MAX_VALUE

src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchELCIntegrationTests.java

+49
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.assertj.core.api.Assertions.*;
1919
import static org.springframework.data.elasticsearch.client.elc.Queries.*;
2020

21+
import co.elastic.clients.elasticsearch._types.SortOrder;
2122
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
2223
import co.elastic.clients.elasticsearch._types.aggregations.Buckets;
2324
import co.elastic.clients.elasticsearch._types.aggregations.StringTermsAggregate;
@@ -27,9 +28,12 @@
2728
import java.util.List;
2829
import java.util.concurrent.atomic.AtomicInteger;
2930

31+
import org.junit.jupiter.api.DisplayName;
32+
import org.junit.jupiter.api.Test;
3033
import org.springframework.context.annotation.Bean;
3134
import org.springframework.context.annotation.Configuration;
3235
import org.springframework.context.annotation.Import;
36+
import org.springframework.data.domain.Pageable;
3337
import org.springframework.data.elasticsearch.client.elc.Aggregation;
3438
import org.springframework.data.elasticsearch.client.elc.ElasticsearchAggregation;
3539
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
@@ -48,6 +52,51 @@
4852
@ContextConfiguration(classes = ReactiveElasticsearchELCIntegrationTests.Config.class)
4953
public class ReactiveElasticsearchELCIntegrationTests extends ReactiveElasticsearchIntegrationTests {
5054

55+
@Test // #2745
56+
@DisplayName("should use sort defined in native unbounded query")
57+
void shouldUseSortDefinedInNativeUnboundedQuery() {
58+
var entity1 = randomEntity(null);
59+
entity1.setRate(7);
60+
var entity2 = randomEntity(null);
61+
entity2.setRate(5);
62+
var entity3 = randomEntity(null);
63+
entity3.setRate(11);
64+
65+
operations.saveAll(List.of(entity1, entity2, entity3), SampleEntity.class).blockLast();
66+
67+
var query = NativeQuery.builder()
68+
.withQuery(qb -> qb
69+
.matchAll(m -> m))
70+
.withSort(sob -> sob
71+
.field(f -> f
72+
.field("rate")
73+
.order(SortOrder.Asc)))
74+
.withPageable(Pageable.unpaged())
75+
.build();
76+
77+
var rates = operations.search(query, SampleEntity.class)
78+
.map(SearchHit::getContent)
79+
.map(SampleEntity::getRate)
80+
.collectList().block();
81+
assertThat(rates).containsExactly(5, 7, 11);
82+
83+
query = NativeQuery.builder()
84+
.withQuery(qb -> qb
85+
.matchAll(m -> m))
86+
.withSort(sob -> sob
87+
.field(f -> f
88+
.field("rate")
89+
.order(SortOrder.Desc)))
90+
.withPageable(Pageable.unpaged())
91+
.build();
92+
93+
rates = operations.search(query, SampleEntity.class)
94+
.map(SearchHit::getContent)
95+
.map(SampleEntity::getRate)
96+
.collectList().block();
97+
assertThat(rates).containsExactly(11, 7, 5);
98+
}
99+
51100
@Configuration
52101
@Import({ ReactiveElasticsearchTemplateConfiguration.class })
53102
static class Config {

src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchIntegrationTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
@SpringIntegrationTest
100100
public abstract class ReactiveElasticsearchIntegrationTests {
101101

102-
@Autowired private ReactiveElasticsearchOperations operations;
102+
@Autowired protected ReactiveElasticsearchOperations operations;
103103
@Autowired private IndexNameProvider indexNameProvider;
104104

105105
// region Setup
@@ -1205,7 +1205,7 @@ void shouldSaveDataFromFluxAndReturnSavedDataInAFlux() {
12051205
// endregion
12061206

12071207
// region Helper functions
1208-
private SampleEntity randomEntity(String message) {
1208+
protected SampleEntity randomEntity(@Nullable String message) {
12091209

12101210
SampleEntity entity = new SampleEntity();
12111211
entity.setId(UUID.randomUUID().toString());

0 commit comments

Comments
 (0)