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 189d95da9..f991b65b1 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
@@ -639,6 +639,30 @@ public interface MongoOperations {
*/
void save(Object objectToSave, String collectionName);
+ /**
+ * 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.
+ *
+ * @param query the query document that specifies the criteria used to select a record to be upserted
+ * @param update the update document that contains the updated object or $ operators to manipulate the existing object
+ * @param entityClass class that determines the collection to use
+ * @return the WriteResult which lets you access the results of the previous write.
+ */
+ WriteResult upsert(Query query, Update update, Class> entityClass);
+
+
+ /**
+ * 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.
+ *
+ * @param query the query document that specifies the criteria used to select a record to be updated
+ * @param update the update document that contains the updated object or $ operators to manipulate the existing
+ * object.
+ * @param collectionName name of the collection to update the object in
+ * @return the WriteResult which lets you access the results of the previous write.
+ */
+ WriteResult upsert(Query query, Update update, String collectionName);
+
/**
* Updates the first object that is found in the collection of the entity class that matches the query document with
* the provided update document.
@@ -647,6 +671,7 @@ public interface MongoOperations {
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
* @param entityClass class that determines the collection to use
+ * @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateFirst(Query query, Update update, Class> entityClass);
@@ -658,6 +683,7 @@ public interface MongoOperations {
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
* @param collectionName name of the collection to update the object in
+ * @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateFirst(Query query, Update update, String collectionName);
@@ -669,6 +695,7 @@ public interface MongoOperations {
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
* @param entityClass class that determines the collection to use
+ * @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateMulti(Query query, Update update, Class> entityClass);
@@ -680,6 +707,7 @@ public interface MongoOperations {
* @param update the update document that contains the updated object or $ operators to manipulate the existing
* object.
* @param collectionName name of the collection to update the object in
+ * @return the WriteResult which lets you access the results of the previous write.
*/
WriteResult updateMulti(Query query, Update update, String collectionName);
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 5c3a295c4..d23b1152c 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
@@ -772,6 +772,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
});
}
+
+ public WriteResult upsert(Query query, Update update, Class> entityClass) {
+ return doUpdate(determineCollectionName(entityClass), query, update, entityClass, true, false);
+ }
+
+ public WriteResult upsert(Query query, Update update, String collectionName) {
+ return doUpdate(collectionName, query, update, null, true, false);
+ }
+
public WriteResult updateFirst(Query query, Update update, Class> entityClass) {
return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, false);
}
@@ -813,11 +822,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
MongoAction mongoAction = new MongoAction(writeConcern, MongoActionOperation.UPDATE, collectionName, entityClass, updateObj, queryObj);
WriteConcern writeConcernToUse = prepareWriteConcern(mongoAction);
if (writeConcernToUse == null) {
- if (multi) {
- wr = collection.updateMulti(queryObj, updateObj);
- } else {
- wr = collection.update(queryObj, updateObj);
- }
+ wr = collection.update(queryObj, updateObj, upsert, multi);
} else {
wr = collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse);
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java
index f87c008dd..2e7bc0bda 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/MappingTests.java
@@ -353,7 +353,31 @@ public class MappingTests {
Person p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
assertThat(p2.getAddress().getCity(), is("New Town"));
}
+
+ @Test
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void testUpsert() {
+ Address addr = new Address();
+ addr.setLines(new String[]{"1234 W. 1st Street", "Apt. 12"});
+ addr.setCity("Anytown");
+ addr.setPostalCode(12345);
+ addr.setCountry("USA");
+ Person p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
+ assertNull(p2);
+
+ template.upsert(query(where("ssn").is(1111).and("firstName").is("Query").and("lastName").is("Update")), update("address", addr), Person.class);
+
+ p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
+ assertThat(p2.getAddress().getCity(), is("Anytown"));
+
+ template.dropCollection(Person.class);
+ template.upsert(query(where("ssn").is(1111).and("firstName").is("Query").and("lastName").is("Update")), update("address", addr), "person");
+ p2 = template.findOne(query(where("ssn").is(1111)), Person.class);
+ assertThat(p2.getAddress().getCity(), is("Anytown"));
+
+ }
+
@Test
public void testOrQuery() {
PersonWithObjectId p1 = new PersonWithObjectId(1, "first", "");
diff --git a/src/docbkx/reference/mongodb.xml b/src/docbkx/reference/mongodb.xml
index 55670b419..ce3bfec87 100644
--- a/src/docbkx/reference/mongodb.xml
+++ b/src/docbkx/reference/mongodb.xml
@@ -1383,6 +1383,18 @@ import static org.springframework.data.mongodb.core.query.Update;
+
+ Upserting documents in a collection
+
+ Related to perfomring an updateFirst
+ operations, you can also perform an upsert operation which will perform
+ an insert if no document is found that matches the query. The document
+ that is inserted is a combination of the query document and the update
+ document. Here is an example
+
+ template.upsert(query(where("ssn").is(1111).and("firstName").is("Joe").and("Fraizer").is("Update")), update("address", addr), Person.class);
+
+
Methods for removing documents