2015-07-17 36 views
6

We wcześniejszych wersjach sterowników MongoDB Java, aby uruchomić kwerendę i zrobić nieuporządkowaną upsert luzem na wynik sumie mieliśmy zrobić, to:Luzem upsert z MongoDB Java 3.0 Sterownik

BulkWriteOperation bulk = dbCollection.initializeUnorderedBulkOperation(); 
    bulk.find(searchQuery).upsert().update(new BasicDBObject("$set", getDbObjectModel())); 

Ale w wersji 3, z wprowadzenie obsługi Bson Document i metody MongoCollection.bulkWrite() w jaki sposób można to zrobić?

Próbowałem to:

List<WriteModel<Document>> documentList = new ArrayList<>(); 

collection.bulkWrite(documentList, new BulkWriteOptions().ordered(false)); 

ale muszę funkcjonalność upsert.

Dzięki.

Odpowiedz

16

Nadal można korzystać z wszystkich funkcji, to po prostu, że BulkWrites mają teraz inną składnię:

MongoCollection<Document> collection = db.getCollection("sample"); 

    List<WriteModel<Document>> updates = Arrays.<WriteModel<Document>>asList(
     new UpdateOneModel<Document>(
       new Document(),     // find part 
       new Document("$set",1),   // update part 
       new UpdateOptions().upsert(true) // options like upsert 
     ) 
    ); 

    BulkWriteResult bulkWriteResult = collection.bulkWrite(updates); 

Więc używania zamówienia UpdateOneModel (lub dla wielu, jeśli chcesz) i ustaw UpdateOptions jako trzecia argument do konstruktora.

Trochę się do tego przyzwyczaja, ale to po prostu budowanie "list" z taką samą składnią, jak gdzie indziej. Sądzę, że to główny powód zmiany.

+0

Czy istnieje oficjalna dokumentacja dla tych zmian w sterowniku? – void

+0

@AswinJoseRoy Przykłady? Niestety, wszystkie przykłady dokumentacji (przynajmniej oficjalne) zdają się podążać za starszymi klasami. To jest ta sama historia dla większości sterowników językowych. Dla mnie znalazłem więcej informacji wyszukując "GitHub" dla "testów" i takich w repozytorium. Ale znowu, niektóre "testy" używają starszych klas "nadal". Więc niektóre są próbą i błędem. Będzie lepiej, a pytania takie jak twoje rzeczywiście pomogą. –

+0

Podczas wstawiania danych po raz pierwszy, zarówno insertedCount i ModifiedCount of bulkWriteResult są równe zero, czy jest to błąd? – inza9hi

0

Jeśli chcesz coś findAndModifyElseCreate(); Oznacza to, że jeśli dokument istnieje, zaktualizuj go, a następnie utwórz go i wstaw dane, a następnie PROSIMY PRZESTRZEGAĆ TEGO.

BasicDBObject insertInCaseDocumentNotFound = new BasicDBObject(); 


insertInCaseDocumentNotFound.put("field1", "value1"); 
insertInCaseDocumentNotFound.put("date", new Date()); 


MongoCollection<BasicDBObject> table = db.getCollection("collectionName",BasicDBObject.class); 

BasicDBObject updateObject = new BasicDBObject(); 

updateObject.append("$setOnInsert", new BasicDBObject()); 
updateObject.append("$set", new BasicDBObject("date",new Date()); 

List<WriteModel<BasicDBObject>> updates = Arrays.<WriteModel<BasicDBObject>> asList(
       new UpdateOneModel<BasicDBObject>(new BasicDBObject("search_name", alert.getString("search_name")), // query for which we need to apply 

         updateObject, // update the document in case it is found 
         new UpdateOptions().upsert(true) // upsert to insert new data in case document is not found 
     )); 
table.bulkWrite(updates); 
4

Oto przykład stosując najnowsze API ..

for (Long entityId : entityIDs) { 

    //Finder doc 
    Document filterDocument = new Document(); 
    filterDocument.append("_id", entityId); 

    //Update doc 
    Document updateDocument = new Document(); 
    Document setDocument = new Document(); 
    setDocument.append("name", "xyz"); 
    setDocument.append("role", "abc"); 

    updateDocument.append("$set", setDocument); 

    //Update option 
    UpdateOptions updateOptions = new UpdateOptions(); 
    updateOptions.upsert(true); //if true, will create a new doc in case of unmatched find 
    updateOptions.bypassDocumentValidation(true); //set true/false 

    //Prepare list of Updates 
    updateDocuments.add(
      new UpdateOneModel<Document>(
        filterDocument, 
        updateDocument, 
        updateOptions)); 

} 

//Bulk write options 
BulkWriteOptions bulkWriteOptions = new BulkWriteOptions(); 
bulkWriteOptions.ordered(false); 
bulkWriteOptions.bypassDocumentValidation(true); 

MongoCollection<Document> mongoCollection = mongoDB.getCollection("myCollection"); 

BulkWriteResult bulkWriteResult = null; 
try { 
    //Perform bulk update 
    bulkWriteResult = mongoCollection.bulkWrite(updateDocuments, 
      bulkWriteOptions); 
} catch (BulkWriteException e) { 
    //Handle bulkwrite exception 
    List<BulkWriteError> bulkWriteErrors = e.getWriteErrors(); 
    for (BulkWriteError bulkWriteError : bulkWriteErrors) { 
     int failedIndex = bulkWriteError.getIndex(); 
     Long failedEntityId = entityIDs.get(failedIndex); 
     System.out.println("Failed record: " + failedEntityId); 
     //handle rollback 
    } 
} 

int rowsUpdated = bulkWriteResult.getModifiedCount(); 

Szczegóły na: http://ashutosh-srivastav-mongodb.blogspot.in/2017/09/mongodb-bulkwrite-java-api.html

+0

To działa dla najnowszej wersji sterownika Java mongo: 3.6.0-rc0 na centralnym repo. –