Spring Data MongoDB: document de mise à jour

Spring Data MongoDB: document de mise à jour

Dans Spring data - MongoDB, vous pouvez utiliser les méthodes suivantes pour mettre à jour les documents.

  1. save - Mettre à jour l'objet entier, si "_id" est présent, effectuer une mise à jour, sinon l'insérer.

  2. updateFirst - Met à jour le premier document qui correspond à la requête.

  3. updateMulti - Met à jour tous les documents qui correspondent à la requête.

  4. Renversement - Si aucun document ne correspond à la requête, un nouveau document est créé en combinant la requête et l'objet de mise à jour.

  5. findAndModify - Même chose avec updateMulti, mais il a une option supplémentaire pour retourner l'ancien ou le nouveau document mis à jour.

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 - exemple de la partie 1

Supposons que les données json ci-dessous soient insérées dans MongoDB.

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

Trouvez le document, modifiez-le et mettez-le à jour avec la méthodesave().

    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);

Sortie

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
Voir l'exemple 2, il montre une erreur courante commise par la plupart des développeurs.

2. saveOrUpdate - exemple de la partie 2

C'est un exemple raté, lu attentivement, une erreur vraiment courante.

Supposons que les données json ci-dessous soient insérées dans MongoDB.

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

DansQuery, vous obtenez le document retourné avec une seule valeur de champ «nom» uniquement, il arrivait souvent d'enregistrer la taille renvoyée par l'objet. L'objet «Utilisateur» renvoyé a une valeur nulle dans les champs: age, ic et createdDate, si vous modifiez le champ «age» et le mettez à jour, il remplacera tout au lieu de mettre à jour le champ modifié - «age».

        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);

Sortie

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]

Après la sauvegarde (), le champ ‘age’ est correctement mis à jour, mais ic et createdDate sont tous deux définis sur null, l’objet “user” entier est mis à jour. Pour mettre à jour une seule valeur de champ / clé, n'utilisez pas save (), utilisez plutôt updateFirst () ou updateMulti ().

3. updatePremier exemple

Met à jour le premier document qui correspond à la requête. Dans ce cas, seul le champ unique «âge» est mis à jour.

{
    "_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);

Sortie

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. Exemple updateMulti

Met à jour tous les documents qui correspondent à la requête.

{
    "_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);
        }

Sortie

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. Exemple renversant

Si le document correspond, mettez-le à jour, sinon créez un nouveau document en combinant la requête et l'objet de mise à jour, cela fonctionne commefindAndModifyElseCreate() :)

{
    //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);

En sortie, un nouveau document est créé en combinant à la fois la requête et l'objet de mise à jour.

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

6. Exemple findAndModify

Recherchez et modifiez et obtenez l'objet nouvellement mis à jour à partir d'une seule opération.

{
    "_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);

Sortie

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

7. Exemple complet

Application complète pour tout combiner de l'exemple 1 à 6.

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);

    }

}

Sortie

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]

Télécharger le code source

Téléchargez-le -SpringMongoDB-Update-Example.zip (29 Ko)