DATAMONGO-1734 - Polish MongoTemplate.exists execution.
Optimize execution by using count() limited to 1 element. Original pull request: #479.
This commit is contained in:
committed by
Mark Paluch
parent
7fb5c7d97c
commit
d3b9f91478
@@ -20,6 +20,7 @@ import static org.springframework.data.mongodb.core.query.SerializationUtils.*;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -131,6 +132,7 @@ import com.mongodb.client.MapReduceIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.CountOptions;
|
||||
import com.mongodb.client.model.CreateCollectionOptions;
|
||||
import com.mongodb.client.model.DeleteOptions;
|
||||
import com.mongodb.client.model.Filters;
|
||||
@@ -609,14 +611,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
}
|
||||
|
||||
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), getPersistentEntity(entityClass));
|
||||
FindIterable<Document> iterable = execute(collectionName, new FindCallback(mappedQuery));
|
||||
|
||||
if (query.getCollation().isPresent()) {
|
||||
iterable = iterable
|
||||
.collation(query.getCollation().map(org.springframework.data.mongodb.core.Collation::toMongoCollation).get());
|
||||
}
|
||||
|
||||
return iterable.iterator().hasNext();
|
||||
return execute(collectionName, new ExistsCallback(mappedQuery,
|
||||
query.getCollation().map(org.springframework.data.mongodb.core.Collation::toMongoCollation).orElse(null)));
|
||||
}
|
||||
|
||||
// Find methods that take a Query to express the query and that return a List of objects.
|
||||
@@ -2429,6 +2426,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimized {@link CollectionCallback} that takes an already mappend query and a nullable
|
||||
* {@link com.mongodb.client.model.Collation} to execute a count query limited to one element.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
private static class ExistsCallback implements CollectionCallback<Boolean> {
|
||||
|
||||
private final Document mappedQuery;
|
||||
private final com.mongodb.client.model.Collation collation;
|
||||
|
||||
@Override
|
||||
public Boolean doInCollection(MongoCollection<Document> collection) throws MongoException, DataAccessException {
|
||||
return collection.count(mappedQuery, new CountOptions().limit(1).collation(collation)) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple {@link CollectionCallback} that takes a query {@link Document} plus an optional fields specification
|
||||
* {@link Document} and executes that against the {@link DBCollection}.
|
||||
|
||||
@@ -81,6 +81,7 @@ import com.mongodb.client.MapReduceIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.CountOptions;
|
||||
import com.mongodb.client.model.DeleteOptions;
|
||||
import com.mongodb.client.model.FindOneAndDeleteOptions;
|
||||
import com.mongodb.client.model.FindOneAndUpdateOptions;
|
||||
@@ -123,6 +124,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
when(db.runCommand(Mockito.any(), Mockito.any(Class.class))).thenReturn(commandResultDocument);
|
||||
when(collection.find(Mockito.any(org.bson.Document.class))).thenReturn(findIterable);
|
||||
when(collection.mapReduce(Mockito.any(), Mockito.any())).thenReturn(mapReduceIterable);
|
||||
when(collection.count(any(), any())).thenReturn(1L);
|
||||
when(findIterable.projection(Mockito.any())).thenReturn(findIterable);
|
||||
when(findIterable.sort(Mockito.any(org.bson.Document.class))).thenReturn(findIterable);
|
||||
when(findIterable.modifiers(Mockito.any(org.bson.Document.class))).thenReturn(findIterable);
|
||||
@@ -666,7 +668,11 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
|
||||
template.exists(new BasicQuery("{}").collation(Collation.of("fr")), AutogenerateableId.class);
|
||||
|
||||
verify(findIterable).collation(eq(com.mongodb.client.model.Collation.builder().locale("fr").build()));
|
||||
ArgumentCaptor<CountOptions> options = ArgumentCaptor.forClass(CountOptions.class);
|
||||
verify(collection).count(any(), options.capture());
|
||||
|
||||
assertThat(options.getValue().getCollation(),
|
||||
is(equalTo(com.mongodb.client.model.Collation.builder().locale("fr").build())));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1518
|
||||
|
||||
Reference in New Issue
Block a user