Skip to content

Commit dffd203

Browse files
authored
Remove the sort from query before executing count. (#1194)
Also creates the query with skip and limit from any Pageable parameter instead of applying it later. Closes #1191.
1 parent 7e2963a commit dffd203

File tree

4 files changed

+37
-14
lines changed

4 files changed

+37
-14
lines changed

src/main/java/org/springframework/data/couchbase/core/query/Query.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ public Query with(final Pageable pageable) {
136136
}
137137
this.limit = pageable.getPageSize();
138138
this.skip = pageable.getOffset();
139-
return with(pageable.getSort());
139+
if(!this.sort.equals(pageable.getSort()))
140+
this.sort.and(pageable.getSort());
141+
return this;
140142
}
141143

142144
/**
@@ -174,6 +176,11 @@ public Query with(final Sort sort) {
174176
return this;
175177
}
176178

179+
public Query withoutSort(){
180+
this.sort = Sort.unsorted();
181+
return this;
182+
}
183+
177184
public void appendSkipAndLimit(final StringBuilder sb) {
178185
if (limit > 0) {
179186
sb.append(" LIMIT ").append(limit);
@@ -287,8 +294,10 @@ public String toN1qlSelectString(ReactiveCouchbaseTemplate template, String coll
287294
appendString(statement, n1ql.selectEntity); // select ...
288295
appendWhereString(statement, n1ql.filter); // typeKey = typeValue
289296
appendWhere(statement, new int[] { 0 }, template.getConverter()); // criteria on this Query
290-
appendSort(statement);
291-
appendSkipAndLimit(statement);
297+
if(!isCount){
298+
appendSort(statement);
299+
appendSkipAndLimit(statement);
300+
}
292301
return statement.toString();
293302
}
294303

src/main/java/org/springframework/data/couchbase/repository/query/CouchbaseQueryExecution.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
import org.springframework.core.convert.converter.Converter;
2121
import org.springframework.data.couchbase.core.CouchbaseOperations;
22-
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.TerminatingFindByQuery;
2322
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.ExecutableFindByQuery;
23+
import org.springframework.data.couchbase.core.ExecutableFindByQueryOperation.TerminatingFindByQuery;
2424
import org.springframework.data.couchbase.core.query.Query;
2525
import org.springframework.data.domain.Pageable;
2626
import org.springframework.data.domain.Slice;
@@ -112,7 +112,7 @@ public SlicedExecution(ExecutableFindByQuery find, Pageable pageable) {
112112
public Object execute(Query query, Class<?> type, String collection) {
113113
int pageSize = pageable.getPageSize();
114114
// Apply Pageable but tweak limit to peek into next page
115-
Query modifiedQuery = query.with(pageable).limit(pageSize + 1);
115+
Query modifiedQuery = query.skip(pageable.getOffset()).limit(pageSize + 1);
116116
List result = find.matching(modifiedQuery).all();
117117
boolean hasNext = result.size() > pageSize;
118118
return new SliceImpl<Object>(hasNext ? result.subList(0, pageSize) : result, pageable, hasNext);
@@ -142,14 +142,12 @@ public PagedExecution(ExecutableFindByQuery<?> operation, Pageable pageable) {
142142
public Object execute(Query query, Class<?> type, String collection) {
143143
int overallLimit = 0; // query.getLimit();
144144
TerminatingFindByQuery<?> matching = operation.matching(query);
145-
// Apply raw pagination
146-
query.with(pageable);
147145
// Adjust limit if page would exceed the overall limit
148146
if (overallLimit != 0 && pageable.getOffset() + pageable.getPageSize() > overallLimit) {
149147
query.limit((int) (overallLimit - pageable.getOffset()));
150148
}
151149
return PageableExecutionUtils.getPage(matching.all(), pageable, () -> {
152-
long count = operation.matching(query.skip(-1).limit(-1)).count();
150+
long count = operation.matching(query.skip(-1).limit(-1).withoutSort()).count();
153151
return overallLimit != 0 ? Math.min(count, overallLimit) : count;
154152
});
155153
}

src/main/java/org/springframework/data/couchbase/repository/query/N1qlQueryCreator.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
import static org.springframework.data.couchbase.core.query.QueryCriteria.where;
2323

2424
import java.util.Iterator;
25+
import java.util.Optional;
2526

2627
import org.springframework.core.convert.converter.Converter;
2728
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
2829
import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty;
2930
import org.springframework.data.couchbase.core.query.N1QLExpression;
3031
import org.springframework.data.couchbase.core.query.Query;
3132
import org.springframework.data.couchbase.core.query.QueryCriteria;
33+
import org.springframework.data.domain.Pageable;
3234
import org.springframework.data.domain.Sort;
3335
import org.springframework.data.mapping.PersistentPropertyPath;
3436
import org.springframework.data.mapping.context.MappingContext;
@@ -37,6 +39,7 @@
3739
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
3840
import org.springframework.data.repository.query.parser.Part;
3941
import org.springframework.data.repository.query.parser.PartTree;
42+
import org.springframework.util.Assert;
4043

4144
/**
4245
* @author Michael Nitschinger
@@ -72,12 +75,24 @@ protected QueryCriteria create(final Part part, final Iterator<Object> iterator)
7275
return from(part, property, where(addMetaIfRequired(bucketName, path, property)), iterator);
7376
}
7477

78+
@Override
79+
public Query createQuery() {
80+
Query q = this.createQuery((Optional.of(this.accessor).map(ParameterAccessor::getSort).orElse(Sort.unsorted())));
81+
Pageable pageable = accessor.getPageable();
82+
if(pageable.isPaged()) {
83+
q.skip(pageable.getOffset());
84+
q.limit(pageable.getPageSize());
85+
}
86+
return q;
87+
}
88+
7589
static Converter<? super CouchbasePersistentProperty, String> cvtr = new MyConverter();
7690

7791
static class MyConverter implements Converter<CouchbasePersistentProperty, String> {
7892
@Override
7993
public String convert(CouchbasePersistentProperty source) {
80-
return new StringBuilder(source.getFieldName().length()+2).append("`").append(source.getFieldName()).append("`").toString();
94+
return new StringBuilder(source.getFieldName().length() + 2).append("`").append(source.getFieldName()).append("`")
95+
.toString();
8196
}
8297
}
8398

@@ -90,7 +105,7 @@ protected QueryCriteria and(final Part part, final QueryCriteria base, final Ite
90105
PersistentPropertyPath<CouchbasePersistentProperty> path = context.getPersistentPropertyPath(part.getProperty());
91106
CouchbasePersistentProperty property = path.getLeafProperty();
92107

93-
return from(part, property, base.and(addMetaIfRequired(bucketName,path, property)), iterator);
108+
return from(part, property, base.and(addMetaIfRequired(bucketName, path, property)), iterator);
94109
}
95110

96111
@Override
@@ -100,7 +115,8 @@ protected QueryCriteria or(QueryCriteria base, QueryCriteria criteria) {
100115

101116
@Override
102117
protected Query complete(QueryCriteria criteria, Sort sort) {
103-
return (criteria == null ? new Query() : new Query().addCriteria(criteria)).with(sort);
118+
Query q = (criteria == null ? new Query() : new Query().addCriteria(criteria)).with(sort);
119+
return q;
104120
}
105121

106122
private QueryCriteria from(final Part part, final CouchbasePersistentProperty property, final QueryCriteria criteria,
@@ -166,8 +182,7 @@ private QueryCriteria from(final Part part, final CouchbasePersistentProperty pr
166182
}
167183
}
168184

169-
public static N1QLExpression addMetaIfRequired(
170-
String bucketName,
185+
public static N1QLExpression addMetaIfRequired(String bucketName,
171186
final PersistentPropertyPath<CouchbasePersistentProperty> persistentPropertyPath,
172187
final CouchbasePersistentProperty property) {
173188
if (property.isIdProperty()) {

src/test/java/org/springframework/data/couchbase/repository/CouchbaseRepositoryQueryIntegrationTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import org.springframework.data.domain.Page;
7777
import org.springframework.data.domain.PageRequest;
7878
import org.springframework.data.domain.Pageable;
79+
import org.springframework.data.domain.Sort;
7980
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
8081
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
8182
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@@ -449,7 +450,7 @@ void count() {
449450
Long count = airportRepository.countFancyExpression(asList("JFK"), asList("jfk"), false);
450451
assertEquals(1, count);
451452

452-
Pageable pageable = PageRequest.of(0, 2);
453+
Pageable pageable = PageRequest.of(0, 2).withSort(Sort.by("iata"));
453454
Page<Airport> aPage = airportRepository.findAllByIataNot("JFK", pageable);
454455
assertEquals(iatas.length - 1, aPage.getTotalElements());
455456
assertEquals(pageable.getPageSize(), aPage.getContent().size());

0 commit comments

Comments
 (0)