2016-03-07 18 views
7

Sto usando MongoDB 3.2 e MongoDB Java Driver 3.2. Ho una serie di un paio di centinaia di documenti aggiornati che dovrebbero ora essere salvati/archiviati in MongoDB. Per fare ciò, eseguo un'iterazione sull'array e richiama per ogni documento in questo array il metodo updateOne().Come eseguire un aggiornamento di massa di documenti in MongoDB con Java

Ora, voglio ri-implementare questa logica con un aggiornamento di massa. Ho provato a trovare un esempio di aggiornamento di massa in MongoDB 3.2 con MongoDB Java Driver 3.2.

Ho provato questo codice:

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

ma sembra che questo approccio si basa su un obsoleto MongoDB Java Driver, come la 2.4 e utilizza metodi obsoleti.

La mia domanda:
come eseguire un aggiornamento di massa dei documenti in MongoDB 3.2 con MongoDB Java Driver 3.2?

+1

guardare l'esempio dettagliata https://stackoverflow.com/a/39356860/4437074 –

risposta

8

Utilizzando l'esempio nel manuale sul nuovo bulkWrite() API, considerare le seguenti raccolta test contenente i seguenti documenti:

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

Il seguente bulkWrite() esegui operazioni multiple sulla raccolta characters:


Involucro:

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

che stampa l'output:

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

    } 
} 

L'equivalente implementazione Java 3.2 segue:

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

per la tua domanda utilizzare il replaceOne() metodo e questo sarebbe stato implementato come

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

Non che io sappia, ma i [Limiti MongoDB e soglie] (https://docs.mongodb.org/manual/reference/limits/) si applicano ancora. – chridam

+1

Grande e grazie. Due domande 1. C'è qualche regola quando devo passare dal singolo aggiornamento all'aggiornamento di massa in "MongoDB"? Voglio dire dalla quantità di documenti punto di regola. 2. Per quanto riguarda 'replaceOne()', tutti i miei documenti aggiornati contengono un aggiornamento di uno-due campi. Perché dovrei usare questo metodo e non 'updateOne()'? Per quanto ho capito, 'replaceOne()' sostituisce l'intero documento, mentre 'updateOne()' può semplicemente aggiornare il valore dei campi specifici, che dovrebbe essere più veloce, ho ragione? –

+1

@MikeB. Penso che questo giustifica una nuova domanda in quanto è diversa da quella che hai originariamente chiesto. Se pubblichi un'altra domanda, sarò altrettanto felice di rispondervi. Il caso generale qui è una domanda una risposta. Posso rispondere alla tua domanda aggiuntiva, ma dovrebbe essere completamente un'altra domanda. Si prega di postarlo separatamente. – chridam