diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
index f3e972e7e..2e2a502c5 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
@@ -711,7 +711,7 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Triggers findAndModify
- * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification. Must not be {@literal null}.
@@ -724,7 +724,7 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Triggers findAndModify
- * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query}.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
* fields specification. Must not be {@literal null}.
@@ -738,7 +738,7 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Triggers findAndModify
- * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
@@ -755,7 +755,7 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Triggers findAndModify
- * * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
+ * to apply provided {@link Update} on documents matching {@link Criteria} of given {@link Query} taking
* {@link FindAndModifyOptions} into account.
*
* @param query the {@link Query} class that specifies the {@link Criteria} used to find a record and also an optional
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
index 1405f57c4..d47b84593 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
@@ -1633,10 +1633,15 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
if (query.getLimit() > 0 || query.getSkip() > 0) {
FindPublisher cursor = new QueryFindPublisherPreparer(query, entityClass)
- .prepare(collection.find(removeQuey)).projection(new Document(ID_FIELD, 1));
- return Flux.from(cursor).map(doc -> doc.get(ID_FIELD)).collectList().flatMap(val -> {
- return Mono.from(collectionToUse.deleteMany(new Document(ID_FIELD, new Document("$in", val)), deleteOptions));
- });
+ .prepare(collection.find(removeQuey)) //
+ .projection(new Document(ID_FIELD, 1));
+
+ return Flux.from(cursor) //
+ .map(doc -> doc.get(ID_FIELD)) //
+ .collectList() //
+ .flatMapMany(val -> {
+ return collectionToUse.deleteMany(new Document(ID_FIELD, new Document("$in", val)), deleteOptions);
+ });
} else {
return collectionToUse.deleteMany(removeQuey, deleteOptions);
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
index a2db9d6e8..f1667ab5b 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
@@ -34,6 +34,8 @@ import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
import org.bson.types.ObjectId;
import org.hamcrest.collection.IsMapContaining;
@@ -3279,9 +3281,11 @@ public class MongoTemplateTests {
@Test // DATAMONGO-1870
public void removeShouldConsiderLimit() {
- for (int i = 0; i < 100; i++) {
- template.save(new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister"));
- }
+ List samples = IntStream.range(0, 100) //
+ .mapToObj(i -> new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister")) //
+ .collect(Collectors.toList());
+
+ template.insertAll(samples);
DeleteResult wr = template.remove(query(where("field").is("lannister")).limit(25), Sample.class);
@@ -3292,9 +3296,11 @@ public class MongoTemplateTests {
@Test // DATAMONGO-1870
public void removeShouldConsiderSkipAndSort() {
- for (int i = 0; i < 100; i++) {
- template.save(new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister"));
- }
+ List samples = IntStream.range(0, 100) //
+ .mapToObj(i -> new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister")) //
+ .collect(Collectors.toList());
+
+ template.insertAll(samples);
DeleteResult wr = template.remove(new Query().skip(25).with(Sort.by("field")), Sample.class);
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java
index 60e137aa1..1f454e430 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateTests.java
@@ -34,6 +34,8 @@ import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
import org.assertj.core.api.Assertions;
import org.bson.Document;
@@ -931,10 +933,11 @@ public class ReactiveMongoTemplateTests {
@Test // DATAMONGO-1870
public void removeShouldConsiderLimit() {
- for (int i = 0; i < 100; i++) {
- StepVerifier.create(template.save(new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister"))).expectNextCount(1)
- .verifyComplete();
- }
+ List samples = IntStream.range(0, 100) //
+ .mapToObj(i -> new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister")) //
+ .collect(Collectors.toList());
+
+ StepVerifier.create(template.insertAll(samples)).expectNextCount(100).verifyComplete();
StepVerifier.create(template.remove(query(where("field").is("lannister")).limit(25), Sample.class))
.assertNext(wr -> Assertions.assertThat(wr.getDeletedCount()).isEqualTo(25L)).verifyComplete();
@@ -943,10 +946,11 @@ public class ReactiveMongoTemplateTests {
@Test // DATAMONGO-1870
public void removeShouldConsiderSkipAndSort() {
- for (int i = 0; i < 100; i++) {
- StepVerifier.create(template.save(new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister"))).expectNextCount(1)
- .verifyComplete();
- }
+ List samples = IntStream.range(0, 100) //
+ .mapToObj(i -> new Sample("id-" + i, i % 2 == 0 ? "stark" : "lannister")) //
+ .collect(Collectors.toList());
+
+ StepVerifier.create(template.insertAll(samples)).expectNextCount(100).verifyComplete();
StepVerifier.create(template.remove(new Query().skip(25).with(Sort.by("field")), Sample.class))
.assertNext(wr -> Assertions.assertThat(wr.getDeletedCount()).isEqualTo(75L)).verifyComplete();
diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc
index 8f15d83f1..594e5cd64 100644
--- a/src/main/asciidoc/reference/mongodb.adoc
+++ b/src/main/asciidoc/reference/mongodb.adoc
@@ -964,11 +964,11 @@ template.findAllAndRemove(query(where("lastname").is("lannister"), "GOT"); <4>
template.findAllAndRemove(new Query().limit(3), "GOT"); <5>
----
-<1> Remove a single entity via its `id` from the associated collection.
+<1> Remove a single entity via its `_id` from the associated collection.
<2> Remove all documents matching the criteria of the query from the `GOT` collection.
-<3> Rewmove the first 3 documents in the `GOT` collection. Unlike <2> the documents to remove are identified via their `id` using the given query applying `sort`, `limit` and `skip` options and then removed all at once in a seperate step.
-<4> Remove all documents matching the criteria of the query from the `GOT` collection. Unlike <3> documents do not get deleted in a batch but one by one.
-<5> Remove the first 3 documents in the `GOT` collection. Unlike <3> documents do not get deleted in a batch but one by one.
+<3> Remove the first 3 documents in the `GOT` collection. Unlike <2>, the documents to remove are identified via their `_id` executing the given query applying `sort`, `limit` and `skip` options first and then remove all at once in a separate step.
+<4> Remove all documents matching the criteria of the query from the `GOT` collection. Unlike <3>, documents do not get deleted in a batch but one by one.
+<5> Remove the first 3 documents in the `GOT` collection. Unlike <3>, documents do not get deleted in a batch but one by one.
====
[[mongo-template.optimistic-locking]]