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 29e583487..0a5cf24fa 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
@@ -1284,7 +1284,9 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
- * combining the query document and the update document.
+ * combining the query document and the update document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, FindAndModifyOptions, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be upserted. Must not be
* {@literal null}.
@@ -1300,6 +1302,9 @@ public interface MongoOperations extends FluentMongoOperations {
* combining the query document and the update document.
* NOTE: Any additional support for field mapping, versions, etc. is not available due to the lack of
* domain type information. Use {@link #upsert(Query, Update, Class, String)} to get full type specific support.
+ *
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, FindAndModifyOptions, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be upserted. Must not be
* {@literal null}.
@@ -1312,8 +1317,10 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
- * combining the query document and the update document.
- *
+ * combining the query document and the update document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, FindAndModifyOptions, Class, String)} instead.
+ *
* @param query the query document that specifies the criteria used to select a record to be upserted. Must not be
* {@literal null}.
* @param update the update document that contains the updated object or $ operators to manipulate the existing
@@ -1326,7 +1333,9 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Updates the first object that is found in the collection of the entity class that matches the query document with
- * the provided update document.
+ * the provided update document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be updated. Must not be
* {@literal null}.
@@ -1342,6 +1351,9 @@ public interface MongoOperations extends FluentMongoOperations {
* the provided updated document.
* NOTE: Any additional support for field mapping, versions, etc. is not available due to the lack of
* domain type information. Use {@link #updateFirst(Query, Update, Class, String)} to get full type specific support.
+ *
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be updated. Must not be
* {@literal null}.
@@ -1355,6 +1367,8 @@ public interface MongoOperations extends FluentMongoOperations {
/**
* Updates the first object that is found in the specified collection that matches the query document criteria with
* the provided updated document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be updated. Must not be
* {@literal null}.
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
index a25328b09..409b84f5d 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
@@ -1625,6 +1625,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
Assert.notNull(query, "Query must not be null!");
Assert.notNull(update, "Update must not be null!");
+ if (query.isSorted() && LOGGER.isWarnEnabled()) {
+
+ LOGGER.warn("{} does not support sort ('{}'). Please use findAndModify() instead.",
+ upsert ? "Upsert" : "UpdateFirst", serializeToJsonSafely(query.getSortObject()));
+ }
+
return execute(collectionName, collection -> {
MongoPersistentEntity> entity = entityClass == null ? null : getPersistentEntity(entityClass);
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java
index 8ef5e5b86..9d68fca4a 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoOperations.java
@@ -1147,7 +1147,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
- * combining the query document and the update document.
+ * combining the query document and the update document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be upserted. Must not be
* {@literal null}.
@@ -1163,6 +1165,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* combining the query document and the update document.
* NOTE: Any additional support for field mapping, versions, etc. is not available due to the lack of
* domain type information. Use {@link #upsert(Query, Update, Class, String)} to get full type specific support.
+ *
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be upserted. Must not be
* {@literal null}.
@@ -1175,7 +1180,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
/**
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
- * combining the query document and the update document.
+ * combining the query document and the update document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be upserted. Must not be
* {@literal null}.
@@ -1189,7 +1196,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
/**
* Updates the first object that is found in the collection of the entity class that matches the query document with
- * the provided update document.
+ * the provided update document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be updated. Must not be
* {@literal null}.
@@ -1205,6 +1214,9 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
* the provided updated document.
* NOTE: Any additional support for field mapping, versions, etc. is not available due to the lack of
* domain type information. Use {@link #updateFirst(Query, Update, Class, String)} to get full type specific support.
+ *
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be updated. Must not be
* {@literal null}.
@@ -1218,6 +1230,8 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
/**
* Updates the first object that is found in the specified collection that matches the query document criteria with
* the provided updated document.
+ * NOTE: {@link Query#getSortObject() sorting} is not supported by {@code db.collection.updateOne}.
+ * Use {@link #findAndModify(Query, Update, Class, String)} instead.
*
* @param query the query document that specifies the criteria used to select a record to be updated. Must not be
* {@literal null}.
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 22a10dbdb..0dcab3e87 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
@@ -1757,6 +1757,12 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
protected Mono doUpdate(String collectionName, Query query, @Nullable UpdateDefinition update,
@Nullable Class> entityClass, boolean upsert, boolean multi) {
+ if (query.isSorted() && LOGGER.isWarnEnabled()) {
+
+ LOGGER.warn("{} does not support sort ('{}'). Please use findAndModify() instead.",
+ upsert ? "Upsert" : "UpdateFirst", serializeToJsonSafely(query.getSortObject()));
+ }
+
MongoPersistentEntity> entity = entityClass == null ? null : getPersistentEntity(entityClass);
Flux result = execute(collectionName, collection -> {
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java
index 13f3891e2..65f23e303 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/BasicQuery.java
@@ -148,6 +148,15 @@ public class BasicQuery extends Query {
this.sortObject = sortObject;
}
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.query.Query#isSorted()
+ */
+ @Override
+ public boolean isSorted() {
+ return super.isSorted() || !sortObject.isEmpty();
+ }
+
/**
* Set the fields (projection) {@link Document}.
*
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java
index 53be757b2..85b92e262 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Query.java
@@ -30,7 +30,6 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.bson.Document;
-
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;
@@ -282,6 +281,17 @@ public class Query {
return document;
}
+ /**
+ * Returns {@literal true} if the {@link Query} has a sort parameter.
+ *
+ * @return {@literal true} if sorted.
+ * @see Sort#isSorted()
+ * @since 2.1.11 / 2.2
+ */
+ public boolean isSorted() {
+ return sort.isSorted();
+ }
+
/**
* Get the number of documents to skip.
*
@@ -530,6 +540,11 @@ public class Query {
public Document getQueryObject() {
return BsonUtils.merge(sourceQuery, super.getQueryObject());
}
+
+ @Override
+ public boolean isSorted() {
+ return source.isSorted() || super.isSorted();
+ }
};
target.criteria.putAll(source.criteria);
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java
index c38098452..8eeb78750 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/TextQuery.java
@@ -180,4 +180,13 @@ public class TextQuery extends Query {
return sort;
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.springframework.data.mongodb.core.query.Query#isSorted()
+ */
+ @Override
+ public boolean isSorted() {
+ return super.isSorted() || sortByScore;
+ }
}
diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc
index e026787f8..5613fb10f 100644
--- a/src/main/asciidoc/reference/mongodb.adoc
+++ b/src/main/asciidoc/reference/mongodb.adoc
@@ -893,6 +893,8 @@ Most methods return the `Update` object to provide a fluent style for the API.
* *updateFirst*: Updates the first document that matches the query document criteria with the updated document.
* *updateMulti*: Updates all objects that match the query document criteria with the updated document.
+WARNING: `updateFirst` does not support ordering. Please use <> to apply `Sort`.
+
[[mongodb-template-update.update]]
==== Methods in the `Update` Class
@@ -944,6 +946,8 @@ Related to performing an `updateFirst` operation, you can also perform an "`upse
template.upsert(query(where("ssn").is(1111).and("firstName").is("Joe").and("Fraizer").is("Update")), update("address", addr), Person.class);
----
+WARNING: `upsert` does not support ordering. Please use <> to apply `Sort`.
+
[[mongo-template.find-and-upsert]]
=== Finding and Upserting Documents in a Collection