2016-03-07 37 views
7

Używam MongoDB 3.2 i MongoDB Java Driver 3.2. Mam zestaw kilkuset zaktualizowanych dokumentów, które powinny być teraz zapisane/przechowywane w MongoDB. W tym celu wykonuję iterację na tablicy i wywołuję dla każdego dokumentu w tej tablicy metodę updateOne().Jak przeprowadzić zbiorczą aktualizację dokumentów w MongoDB za pomocą Java

Teraz chcę ponownie wdrożyć tę logikę za pomocą aktualizacji zbiorczej. Próbowałem znaleźć przykład aktualizacji zbiorczej w wersji MongoDB 3.2 z MongoDB Java Driver 3.2.

Próbowałem ten kod:

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

Ale wydaje się, że takie podejście jest oparte na przestarzałej MongoDB Java Driver, takie jak 2.4 i wykorzystuje metody przestarzałe.

Moje pytanie:
Jak wykonać zbiorczą aktualizację dokumentów w MongoDB 3.2 z MongoDB Java Driver 3.2?

+1

Spójrz na szczegółowym przykładzie https://stackoverflow.com/a/39356860/4437074 –

Odpowiedz

8

Korzystanie przykład w podręczniku na nowym bulkWrite() API, rozważmy następujący zbiór testowy, który zawiera następujące dokumenty:

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

Poniższy bulkWrite() wykonuje wiele operacji na zbiorach 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); } 

która drukuje dane wyjściowe:

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

    } 
} 

Odpowiednik Java 3.2 realizacja następuje:

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

za pytanie korzystania z replaceOne() metoda i to będzie realizowane jako

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

Nie, że jestem świadomy, ale [Granice MongoDB i progów] (https://docs.mongodb.org/manual/reference/limits/) nadal mają zastosowanie. – chridam

+1

Świetne i dzięki. Dwa pytania. 1. Czy istnieje jakakolwiek zasada, kiedy muszę przejść z pojedynczej aktualizacji do aktualizacji zbiorczej w 'MongoDB'? Mam na myśli ilość dokumentów z punktu widzenia reguły. 2. Jeśli chodzi o 'replaceOne()', wszystkie moje zaktualizowane dokumenty zawierają aktualizację jednego-dwóch pól. Dlaczego powinienem używać tej metody, a nie 'updateOne()'? O ile rozumiem, 'replaceOne()' zastępuje cały dokument, podczas gdy 'updateOne()' może po prostu zaktualizować wartość określonych pól, co powinno być szybsze, czy mam rację? –

+1

@MikeB. Myślę, że to uzasadnia nowe pytanie, ponieważ różni się ono od pierwotnie zadawanych pytań. Jeśli opublikujesz kolejne pytanie, będę tak samo szczęśliwy, jak na nie odpowiem. Ogólny przypadek tutaj to jedno pytanie jedna odpowiedź. Mogę odpowiedzieć na twoje dodatkowe pytanie, ale powinno to być zupełnie inne pytanie. Opublikuj go osobno. – chridam