web-dev-qa-db-de.com

Massen-Upsert mit MongoDB Java 3.0-Treiber

In früheren Versionen von MongoDB Java-Treibern mussten wir nur Folgendes tun, um eine Abfrage auszuführen und eine ungeordnete Massenverschiebung des Ergebnisses vorzunehmen:

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

Wie kann dies in Version 3 mit der Einführung der Bson Document-Unterstützung und der MongoCollection.bulkWrite () -Methode geschehen?

Ich habe es versucht:

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

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

aber ich brauche die Upsert-Funktionalität.

Vielen Dank.

10
void

Sie können weiterhin alle Funktionen nutzen. BulkWrites haben nur eine andere Syntax:

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

Sie verwenden also die UpdateOneModel (oder für viele, wenn Sie möchten) und setzen die UpdateOptions als drittes Argument für den Konstruktor.

Es ist gewöhnungsbedürftig, aber im Grunde genommen werden nur "Listen" mit der gleichen Syntax wie anderswo erstellt. Ich denke, das ist der Hauptgrund für die Änderung.

20
Blakes Seven

Hier ist das Beispiel mit den neuesten APIs.

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

Details unter: http://ashutosh-srivastav-mongodb.blogspot.in/2017/09/mongodb-bulkwrite-Java-api.html

5

Wenn Sie etwas wollen findAndModifyElseCreate (); Das heißt, wenn das Dokument existiert, aktualisieren Sie es, erstellen Sie es und fügen Sie die Daten ein. BITTE FOLGEN SIE DIESEM.

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