Browse Source

DATAMONGO-870 - Added support for sliced query execution.

Added support for Slice as return type for query methods. The execution will expand the requested page size by one to read one more element than actually requested. If that additional element is returned, it will considered to be an indicator for whether a next slice is available.

Related issues: DATACMNS-397.
pull/138/merge
Oliver Gierke 12 years ago
parent
commit
6963f9e07a
  1. 40
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java
  2. 30
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java
  3. 7
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java

40
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/AbstractMongoQuery.java

@ -20,7 +20,10 @@ import java.util.List; @@ -20,7 +20,10 @@ import java.util.List;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.geo.Distance;
import org.springframework.data.mongodb.core.geo.GeoPage;
@ -87,6 +90,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { @@ -87,6 +90,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
return new GeoNearExecution(accessor).execute(query, countQuery);
} else if (method.isGeoNearQuery()) {
return new GeoNearExecution(accessor).execute(query);
} else if (method.isSliceQuery()) {
return new SlicedExecution(accessor.getPageable()).execute(query);
} else if (method.isCollectionQuery()) {
return new CollectionExecution(accessor.getPageable()).execute(query);
} else if (method.isPageQuery()) {
@ -171,6 +176,41 @@ public abstract class AbstractMongoQuery implements RepositoryQuery { @@ -171,6 +176,41 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
}
}
/**
* {@link Execution} for {@link Slice} query methods.
*
* @author Oliver Gierke
* @since 1.5
*/
final class SlicedExecution extends Execution {
private final Pageable pageable;
SlicedExecution(Pageable pageable) {
this.pageable = pageable;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query)
*/
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
Object execute(Query query) {
MongoEntityMetadata<?> metadata = method.getEntityInformation();
int pageSize = pageable.getPageSize();
Pageable slicePageable = new PageRequest(pageable.getPageNumber(), pageSize + 1, pageable.getSort());
List result = operations.find(query.with(slicePageable), metadata.getJavaType(), metadata.getCollectionName());
boolean hasNext = result.size() > pageSize;
return new SliceImpl<Object>(hasNext ? result.subList(0, pageSize) : result, pageable, hasNext);
}
}
/**
* {@link Execution} for pagination queries.
*

30
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoOperations;
@ -155,8 +156,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { @@ -155,8 +156,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
public void findsPagedPersons() throws Exception {
Page<Person> result = repository.findAll(new PageRequest(1, 2, Direction.ASC, "lastname", "firstname"));
assertThat(result.isFirstPage(), is(false));
assertThat(result.isLastPage(), is(false));
assertThat(result.isFirst(), is(false));
assertThat(result.isLast(), is(false));
assertThat(result, hasItems(dave, stefan));
}
@ -165,8 +166,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { @@ -165,8 +166,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
Page<Person> page = repository.findByLastnameLike("*a*", new PageRequest(0, 2, Direction.ASC, "lastname",
"firstname"));
assertThat(page.isFirstPage(), is(true));
assertThat(page.isLastPage(), is(false));
assertThat(page.isFirst(), is(true));
assertThat(page.isLast(), is(false));
assertThat(page.getNumberOfElements(), is(2));
assertThat(page, hasItems(carter, stefan));
}
@ -176,8 +177,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { @@ -176,8 +177,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
Page<Person> page = repository.findByLastnameLikeWithPageable(".*a.*", new PageRequest(0, 2, Direction.ASC,
"lastname", "firstname"));
assertThat(page.isFirstPage(), is(true));
assertThat(page.isLastPage(), is(false));
assertThat(page.isFirst(), is(true));
assertThat(page.isLast(), is(false));
assertThat(page.getNumberOfElements(), is(2));
assertThat(page, hasItems(carter, stefan));
}
@ -301,8 +302,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests { @@ -301,8 +302,8 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
Page<Person> page = repository.findAll(person.lastname.contains("a"), new PageRequest(0, 2, Direction.ASC,
"lastname"));
assertThat(page.isFirstPage(), is(true));
assertThat(page.isLastPage(), is(false));
assertThat(page.isFirst(), is(true));
assertThat(page.isLast(), is(false));
assertThat(page.getNumberOfElements(), is(2));
assertThat(page, hasItems(carter, stefan));
}
@ -738,4 +739,15 @@ public abstract class AbstractPersonRepositoryIntegrationTests { @@ -738,4 +739,15 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
assertThat(result.size(), is(1));
assertThat(result.get(0), is(dave));
}
/**
* @see DATAMONGO-870
*/
@Test
public void findsSliceOfPersons() {
Slice<Person> result = repository.findByAgeGreaterThan(40, new PageRequest(0, 2, Direction.DESC, "firstname"));
assertThat(result.hasNext(), is(true));
}
}

7
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2013 the original author or authors.
* Copyright 2010-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.List; @@ -21,6 +21,7 @@ import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.geo.Box;
import org.springframework.data.mongodb.core.geo.Circle;
@ -245,4 +246,8 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query @@ -245,4 +246,8 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
*/
List<Person> findByFirstnameContainingIgnoreCase(String firstName);
/**
* @see DATAMONGO-870
*/
Slice<Person> findByAgeGreaterThan(int age, Pageable pageable);
}

Loading…
Cancel
Save