Массовое обновление с помощью драйвера MongoDB Java 3.0

В более ранних версиях Java-драйверов MongoDB для запуска запроса и выполнения неупорядоченной массовой отправки результатов все, что нам нужно было сделать, это:

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

Но в версии 3, с введением поддержки Bson Document и метода MongoCollection.bulkWrite(), как это можно сделать?

Я пробовал это:

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

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

но мне нужна функция upsert.

Спасибо.


person void    schedule 17.07.2015    source источник


Ответы (3)


Вы по-прежнему можете использовать все функции, просто у BulkWrites теперь другой синтаксис:

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

Таким образом, вы используете UpdateOneModel (или для многих если хотите) и установите UpdateOptions как третий аргумент конструктора.

Требуется некоторое привыкание, но в основном это просто создание «списков» с тем же синтаксисом, что и везде. Думаю, это основная причина замены.

person Blakes Seven    schedule 17.07.2015
comment
Есть ли официальная документация по этим изменениям в драйвере? - person void; 17.07.2015
comment
Примеры @AswinJoseRoy? Нет. К сожалению, все примеры документации (по крайней мере, официальные) следуют старым классам. Та же история и с большинством языковых драйверов. Что касается меня, я нашел больше информации, выполнив поиск на GitHub тестов и тому подобного в репозитории. Но опять же, в некоторых тестах все еще используются старые классы. Так что некоторые методом проб и ошибок. Будет лучше, и такие вопросы, как ваш, действительно помогают. - person Blakes Seven; 17.07.2015
comment
При вставке данных в первый раз как InsertCount, так и ModifiedCount из bulkWriteResult равны нулю, это ошибка? - person inza9hi; 30.08.2016

Вот пример с использованием последних 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();

Подробности по адресу: https://ashutosh-srivastav-mongodb.blogspot.in/2017/09/mongodb-bulkwrite-java-api.html

person Ashutosh Srivastav    schedule 06.09.2016
comment
Это работает для последней версии драйвера Java mongo: 3.6.0-rc0 в центральном репо. - person Binita Bharati; 11.12.2017
comment
+1 работает, List<WriteModel<Document>> updateDocuments = new ArrayList<WriteModel<Document>>(); Ссылка не работает, вот ashutosh-srivastav-mongodb.blogspot.com/2017/09/ - person Eswar Goud; 22.07.2020

Если вам нужно что-то findAndModifyElseCreate(); Это означает, что если документ существует, обновите его, иначе создайте его и вставьте данные, а затем ПОЖАЛУЙСТА, СЛЕДУЙТЕ ЭТОМУ.

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);
person Sanchit Singhania    schedule 03.06.2016