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 c056517e7..038e998e4 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
@@ -770,7 +770,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}.
@@ -783,7 +783,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}.
@@ -797,7 +797,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
@@ -814,7 +814,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 a1e67550a..f7e31741e 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
@@ -1702,10 +1702,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 f2aaa726e..9aa7990b5 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;
@@ -3330,9 +3332,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);
@@ -3343,9 +3347,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 4dd0cd5e7..a70263305 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
@@ -36,6 +36,7 @@ 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.assertj.core.api.Assumptions;
@@ -1127,10 +1128,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();
@@ -1139,10 +1141,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 73126d7c4..685ce9ba1 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]]