web-dev-qa-db-fra.com

Comment effectuer une mise à jour groupée de documents dans MongoDB avec Java

J'utilise MongoDB 3.2 et MongoDB Java Driver 3.2. J'ai un tableau de quelques centaines de documents mis à jour qui devraient maintenant être enregistrés/stockés dans MongoDB. Pour ce faire, je parcourir le tableau et appeler pour chaque document de ce tableau la méthode updateOne().

Maintenant, je veux réimplémenter cette logique avec une mise à jour groupée. J'ai essayé de trouver un exemple de mise à jour groupée dans MongoDB 3.2 avec MongoDB Java Driver 3.2.

J'ai essayé ce code:

MongoClient mongo = new MongoClient("localhost", 27017);
DB db = (DB) mongo.getDB("test1");
DBCollection collection = db.getCollection("collection");
BulkWriteOperation builder = collection.initializeUnorderedBulkOperation();
builder.find(new BasicDBObject("_id", 1001)).upsert()
    .replaceOne(new BasicDBObject("_id", 1001).append("author", "newName"));

builder.execute();

Mais il semble que cette approche soit basée sur un MongoDB obsolète Java Driver, tel que 2.4 et utilise des méthodes obsolètes.

Ma question:
Comment effectuer une mise à jour groupée de documents dans MongoDB 3.2 avec MongoDB Java Driver 3.2?

15
Mike B.

En utilisant l'exemple du manuel sur la nouvelle bulkWrite() API, considérez la collection de tests suivante qui contient Les documents suivants:

{ "_id" : 1, "char" : "Brisbane", "class" : "monk", "lvl" : 4 },
{ "_id" : 2, "char" : "Eldon", "class" : "alchemist", "lvl" : 3 },
{ "_id" : 3, "char" : "Meldane", "class" : "ranger", "lvl" : 3 }

Les éléments suivants bulkWrite() effectuent plusieurs opérations sur la collection characters:


Mongo Shell:

try {
    db.characters.bulkWrite([
        { 
            insertOne:{
                "document":{
                    "_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
                }
            }
        },
        { 
            insertOne:{
                "document": {
                    "_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
                }
            }
        },
        { 
            updateOne: {
                "filter" : { "char" : "Eldon" },
                "update" : { $set : { "status" : "Critical Injury" } }
            }
        },
        { 
            deleteOne: { "filter" : { "char" : "Brisbane"} }
        },
        { 
            replaceOne: {
               "filter" : { "char" : "Meldane" },
               "replacement" : { "char" : "Tanys", "class" : "Oracle", "lvl" : 4 }
            }
        }
    ]);
}
catch (e) {  print(e); }

qui imprime la sortie:

{
   "acknowledged" : true,
   "deletedCount" : 1,
   "insertedCount" : 2,
   "matchedCount" : 2,
   "upsertedCount" : 0,
   "insertedIds" : {
      "0" : 4,
      "1" : 5
   },
   "upsertedIds" : {

   }
}

L'implémentation équivalente Java 3.2 suit:

MongoCollection<Document> collection = db.getCollection("characters");
List<WriteModel<Document>> writes = new ArrayList<WriteModel<Document>>();
writes.add(
    new InsertOneModel<Document>(
        new Document("_id", 4)
            .append("char", "Dithras")
            .append("class", "barbarian")
            .append("lvl", 3)
    )
);
writes.add(
    new InsertOneModel<Document>(
        new Document("_id", 5)
            .append("char", "Taeln")
            .append("class", "fighter")
            .append("lvl", 4)
    )
);
writes.add(
    new UpdateOneModel<Document>(
        new Document("char", "Eldon"), // filter
        new Document("$set", new Document("status", "Critical Injury")) // update
    )
);
writes.add(new DeleteOneModel<Document>(new Document("char", "Brisbane")));
writes.add(
    new ReplaceOneModel<Document>(
        new Document("char", "Meldane"), 
        new Document("char", "Tanys")
            .append("class", "Oracle")
            .append("lvl", 4)           
    )
);

BulkWriteResult bulkWriteResult = collection.bulkWrite(writes);

Pour votre question, utilisez la méthode replaceOne() et celle-ci sera implémentée comme

MongoCollection<Document> collection = db.getCollection("collection");
List<WriteModel<Document>> writes = Arrays.<WriteModel<Document>>asList(
    new ReplaceOneModel<Document>(
        new Document("_id", 1001), // filter
        new Document("author", "newName"), // update
        new UpdateOptions().upsert(true) // options
    )   
);

BulkWriteResult bulkWriteResult = collection.bulkWrite(writes);
16
chridam