Spring Data MongoDB: Dokument aktualisieren

Spring Data MongoDB: Dokument aktualisieren

In Spring Data - MongoDB können Sie die folgenden Methoden zum Aktualisieren von Dokumenten verwenden.

  1. Speichern - Aktualisieren Sie das gesamte Objekt, wenn "_id" vorhanden ist, führen Sie eine Aktualisierung durch, andernfalls fügen Sie es ein.

  2. updateFirst - Aktualisiert das erste Dokument, das der Abfrage entspricht.

  3. updateMulti - Aktualisiert alle Dokumente, die der Abfrage entsprechen.

  4. Upserting - Wenn kein Dokument mit der Abfrage übereinstimmt, wird ein neues Dokument erstellt, indem Abfrage und Aktualisierungsobjekt kombiniert werden.

  5. findAndModify - Entspricht updateMulti, bietet jedoch eine zusätzliche Option, um entweder das alte oder das neu aktualisierte Dokument zurückzugeben.

P.S All examples are tested under mongo-java-driver-2.11.0.jar and `spring-data-mongodb-1.2.0.RELEASE.jar`

1. saveOrUpdate - Teil 1 Beispiel

Angenommen, die folgenden json-Daten werden in MongoDB eingefügt.

{
    "_id" : ObjectId("id"),
    "ic" : "1001",
    "name" : "appleA",
    "age" : 20,
    "createdDate" : ISODate("2013-04-06T23:17:35.530Z")
}

Suchen Sie das Dokument, ändern und aktualisieren Sie es mit der Methodesave().

    Query query = new Query();
    query.addCriteria(Criteria.where("name").is("appleA"));

    User userTest1 = mongoOperation.findOne(query, User.class);

    System.out.println("userTest1 - " + userTest1);

    //modify and update with save()
    userTest1.setAge(99);
    mongoOperation.save(userTest1);

    //get the updated object again
    User userTest1_1 = mongoOperation.findOne(query, User.class);

    System.out.println("userTest1_1 - " + userTest1_1);

Ausgabe

userTest1 - User [id=id, ic=1001, name=appleA, age=20, createdDate=Sat Apr 06 23:17:35 MYT 2013]
userTest1_1 - User [id=id, ic=1001, name=appleA, age=99, createdDate=Sat Apr 06 23:17:35 MYT 2013]

Note
Siehe Beispiel 2, es zeigt einen häufigen Fehler, den die meisten Entwickler gemacht haben.

2. saveOrUpdate - Teil 2 Beispiel

Dies ist ein fehlgeschlagenes Beispiel, lesen Sie sorgfältig, ein wirklich häufiger Fehler.

Angenommen, die folgenden json-Daten werden in MongoDB eingefügt.

{
    "_id" : ObjectId("id"),
    "ic" : "1002",
    "name" : "appleB",
    "age" : 20,
    "createdDate" : ISODate("2013-04-06T15:22:34.530Z")
}

InQuery wird das Dokument nur mit einem einzigen Feldwert "Name" zurückgegeben. Es kam häufig vor, dass die zurückgegebene Objektgröße gespeichert wurde. Das zurückgegebene "User" -Objekt hat in den Feldern "age", "ic" und "createdDate" einen Nullwert. Wenn Sie das Feld "age" ändern und aktualisieren, wird alles außer Kraft gesetzt, anstatt das geänderte Feld "age" zu aktualisieren.

        Query query = new Query();
        query.addCriteria(Criteria.where("name").is("appleB"));
        query.fields().include("name");

        User userTest2 = mongoOperation.findOne(query, User.class);
        System.out.println("userTest2 - " + userTest2);

        userTest2.setAge(99);

        mongoOperation.save(userTest2);

        // ooppss, you just override everything, it caused ic=null and
        // createdDate=null

        Query query1 = new Query();
        query1.addCriteria(Criteria.where("name").is("appleB"));

        User userTest2_1 = mongoOperation.findOne(query1, User.class);
        System.out.println("userTest2_1 - " + userTest2_1);

Ausgabe

userTest2 - User [id=51603dba3004d7fffc202391, ic=null, name=appleB, age=0, createdDate=null]
userTest2_1 - User [id=51603dba3004d7fffc202391, ic=null, name=appleB, age=99, createdDate=null]

Nach dem Speichern () wird das Feld "Alter" korrekt aktualisiert, aber ic und createdDate werden beide auf null gesetzt, und das gesamte "Benutzer" -Objekt wird aktualisiert. Verwenden Sie zum Aktualisieren eines einzelnen Felds / Schlüsselwerts nicht save (), sondern updateFirst () oder updateMulti ().

3. updateFirst Beispiel

Aktualisiert das erste Dokument, das der Abfrage entspricht. In diesem Fall wird nur das einzelne Feld "Alter" aktualisiert.

{
    "_id" : ObjectId("id"),
    "ic" : "1003",
    "name" : "appleC",
    "age" : 20,
    "createdDate" : ISODate("2013-04-06T23:22:34.530Z")
}
        //returns only 'name' field
        Query query = new Query();
        query.addCriteria(Criteria.where("name").is("appleC"));
        query.fields().include("name");

        User userTest3 = mongoOperation.findOne(query, User.class);
        System.out.println("userTest3 - " + userTest3);

        Update update = new Update();
        update.set("age", 100);

        mongoOperation.updateFirst(query, update, User.class);

        //returns everything
        Query query1 = new Query();
        query1.addCriteria(Criteria.where("name").is("appleC"));

        User userTest3_1 = mongoOperation.findOne(query1, User.class);
        System.out.println("userTest3_1 - " + userTest3_1);

Ausgabe

userTest3 - User [id=id, ic=null, name=appleC, age=0, createdDate=null]
userTest3_1 - User [id=id, ic=1003, name=appleC, age=100, createdDate=Sat Apr 06 23:22:34 MYT 2013]

4. updateMulti Beispiel

Aktualisiert alle Dokumente, die der Abfrage entsprechen.

{
    "_id" : ObjectId("id"),
    "ic" : "1004",
    "name" : "appleD",
    "age" : 20,
    "createdDate" : ISODate("2013-04-06T15:22:34.530Z")
}
{
    "_id" : ObjectId("id"),
    "ic" : "1005",
    "name" : "appleE",
    "age" : 20,
    "createdDate" : ISODate("2013-04-06T15:22:34.530Z")
}
        //show the use of $or operator
        Query query = new Query();
        query.addCriteria(Criteria
                .where("name").exists(true)
                .orOperator(Criteria.where("name").is("appleD"),
                        Criteria.where("name").is("appleE")));
        Update update = new Update();

        //update age to 11
        update.set("age", 11);

        //remove the createdDate field
        update.unset("createdDate");

        // if use updateFirst, it will update 1004 only.
        // mongoOperation.updateFirst(query4, update4, User.class);

        // update all matched, both 1004 and 1005
        mongoOperation.updateMulti(query, update, User.class);

        System.out.println(query.toString());

        List usersTest4 = mongoOperation.find(query4, User.class);

        for (User userTest4 : usersTest4) {
            System.out.println("userTest4 - " + userTest4);
        }

Ausgabe

Query: { "name" : { "$exists" : true} ,
    "$or" : [ { "name" : "appleD"} , { "name" : "appleE"}]}, Fields: null, Sort: null

userTest4 - User [id=id, ic=1004, name=appleD, age=11, createdDate=null]
userTest4 - User [id=id, ic=1005, name=appleE, age=11, createdDate=null]

5. Beispiel auf den Kopf stellen

Wenn das Dokument übereinstimmt, aktualisieren Sie es. Andernfalls erstellen Sie ein neues Dokument, indem Sie die Abfrage und das Aktualisierungsobjekt kombinieren. Es funktioniert wiefindAndModifyElseCreate() :)

{
    //no data
}
        //search a document that doesn't exist
        Query query = new Query();
        query.addCriteria(Criteria.where("name").is("appleZ"));

        Update update = new Update();
        update.set("age", 21);

        mongoOperation.upsert(query, update, User.class);

        User userTest5 = mongoOperation.findOne(query, User.class);
        System.out.println("userTest5 - " + userTest5);

Bei der Ausgabe wird ein neues Dokument erstellt, indem sowohl das Abfrage- als auch das Aktualisierungsobjekt kombiniert werden.

userTest5 - User [id=id, ic=null, name=appleZ, age=21, createdDate=null]

6. findAndModify Beispiel

Suchen und ändern Sie das neu aktualisierte Objekt und rufen Sie es mit einem einzigen Vorgang ab.

{
    "_id" : ObjectId("id"),
    "ic" : "1006",
    "name" : "appleF",
    "age" : 20,
    "createdDate" : ISODate("2013-04-07T13:11:34.530Z")
}
        Query query6 = new Query();
        query6.addCriteria(Criteria.where("name").is("appleF"));

        Update update6 = new Update();
        update6.set("age", 101);
        update6.set("ic", 1111);

        //FindAndModifyOptions().returnNew(true) = newly updated document
        //FindAndModifyOptions().returnNew(false) = old document (not update yet)
        User userTest6 = mongoOperation.findAndModify(
                query6, update6,
                new FindAndModifyOptions().returnNew(true), User.class);
        System.out.println("userTest6 - " + userTest6);

Ausgabe

userTest6 - User [id=id, ic=1111, name=appleF, age=101, createdDate=Sun Apr 07 13:11:34 MYT 2013]

7. Vollständiges Beispiel

Volle Anwendung, um alles von Beispiel 1 bis 6 zu kombinieren.

package com.example.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.example.config.SpringMongoConfig;
import com.example.model.User;

public class UpdateApp {

    public static void main(String[] args) {
        // For Annotation
        ApplicationContext ctx =
            new AnnotationConfigApplicationContext(SpringMongoConfig.class);
        MongoOperations mongoOperation =
            (MongoOperations) ctx.getBean("mongoTemplate");

        // insert 6 users for testing
        List users = new ArrayList();

        User user1 = new User("1001", "appleA", 20, new Date());
        User user2 = new User("1002", "appleB", 20, new Date());
        User user3 = new User("1003", "appleC", 20, new Date());
        User user4 = new User("1004", "appleD", 20, new Date());
        User user5 = new User("1005", "appleE", 20, new Date());
        User user6 = new User("1006", "appleF", 20, new Date());
        users.add(user1);
        users.add(user2);
        users.add(user3);
        users.add(user4);
        users.add(user5);
        users.add(user6);
        mongoOperation.insert(users, User.class);

        // Case 1 ... find and update
        System.out.println("Case 1");

        Query query1 = new Query();
        query1.addCriteria(Criteria.where("name").is("appleA"));

        User userTest1 = mongoOperation.findOne(query1, User.class);

        System.out.println("userTest1 - " + userTest1);

        userTest1.setAge(99);
        mongoOperation.save(userTest1);

        User userTest1_1 = mongoOperation.findOne(query1, User.class);

        System.out.println("userTest1_1 - " + userTest1_1);

        // Case 2 ... select single field only
        System.out.println("\nCase 2");

        Query query2 = new Query();
        query2.addCriteria(Criteria.where("name").is("appleB"));
        query2.fields().include("name");

        User userTest2 = mongoOperation.findOne(query2, User.class);
        System.out.println("userTest2 - " + userTest2);

        userTest2.setAge(99);

        mongoOperation.save(userTest2);

        // ooppss, you just override everything, it caused ic=null and
        // createdDate=null

        Query query2_1 = new Query();
        query2_1.addCriteria(Criteria.where("name").is("appleB"));

        User userTest2_1 = mongoOperation.findOne(query2_1, User.class);
        System.out.println("userTest2_1 - " + userTest2_1);

        System.out.println("\nCase 3");
        Query query3 = new Query();
        query3.addCriteria(Criteria.where("name").is("appleC"));
        query3.fields().include("name");

        User userTest3 = mongoOperation.findOne(query3, User.class);
        System.out.println("userTest3 - " + userTest3);

        Update update3 = new Update();
        update3.set("age", 100);

        mongoOperation.updateFirst(query3, update3, User.class);

        Query query3_1 = new Query();
        query3_1.addCriteria(Criteria.where("name").is("appleC"));

        User userTest3_1 = mongoOperation.findOne(query3_1, User.class);
        System.out.println("userTest3_1 - " + userTest3_1);

        System.out.println("\nCase 4");
        Query query4 = new Query();
        query4.addCriteria(Criteria
                .where("name")
                .exists(true)
                .orOperator(Criteria.where("name").is("appleD"),
                        Criteria.where("name").is("appleE")));
        Update update4 = new Update();
        update4.set("age", 11);
        update4.unset("createdDate");

        // update 1004 only.
        // mongoOperation.updateFirst(query4, update4, User.class);

        // update all matched
        mongoOperation.updateMulti(query4, update4, User.class);

        System.out.println(query4.toString());

        List usersTest4 = mongoOperation.find(query4, User.class);

        for (User userTest4 : usersTest4) {
            System.out.println("userTest4 - " + userTest4);
        }

        System.out.println("\nCase 5");
        Query query5 = new Query();
        query5.addCriteria(Criteria.where("name").is("appleZ"));

        Update update5 = new Update();
        update5.set("age", 21);

        mongoOperation.upsert(query5, update5, User.class);

        User userTest5 = mongoOperation.findOne(query5, User.class);
        System.out.println("userTest5 - " + userTest5);

        System.out.println("\nCase 6");
        Query query6 = new Query();
        query6.addCriteria(Criteria.where("name").is("appleF"));

        Update update6 = new Update();
        update6.set("age", 101);
        update6.set("ic", 1111);

        User userTest6 = mongoOperation.findAndModify(query6, update6,
                new FindAndModifyOptions().returnNew(true), User.class);
        System.out.println("userTest6 - " + userTest6);

        mongoOperation.dropCollection(User.class);

    }

}

Ausgabe

Case 1
userTest1 - User [id=id, ic=1001, name=appleA, age=20, createdDate=Sun Apr 07 13:22:48 MYT 2013]
userTest1_1 - User [id=id, ic=1001, name=appleA, age=99, createdDate=Sun Apr 07 13:22:48 MYT 2013]

Case 2
userTest2 - User [id=id, ic=null, name=appleB, age=0, createdDate=null]
userTest2_1 - User [id=id, ic=null, name=appleB, age=99, createdDate=null]

Case 3
userTest3 - User [id=id, ic=null, name=appleC, age=0, createdDate=null]
userTest3_1 - User [id=id, ic=1003, name=appleC, age=100, createdDate=Sun Apr 07 13:22:48 MYT 2013]

Case 4
Query: { "name" : { "$exists" : true} , "$or" : [ { "name" : "appleD"} , { "name" : "appleE"}]}, Fields: null, Sort: null
userTest4 - User [id=id, ic=1004, name=appleD, age=11, createdDate=null]
userTest4 - User [id=id, ic=1005, name=appleE, age=11, createdDate=null]

Case 5
userTest5 - User [id=id, ic=null, name=appleZ, age=21, createdDate=null]

Case 6
userTest6 - User [id=id, ic=1006, name=appleF, age=20, createdDate=Sun Apr 07 13:22:48 MYT 2013]

Quellcode herunterladen

Laden Sie es herunter -SpringMongoDB-Update-Example.zip (29 KB)