Как поместить существующую запись в MongoDB, чтобы не создавался новый документ?

Как эффективно опубликовать документ в MongoDB, не проверяя, есть ли он уже в коллекции. В настоящее время в моем коде JAVA я сначала проверяю наличие документа, а затем, если его нет, я его публикую. Кажется, это очень медленно, потому что для каждого документа я размещаю два запроса.

Разве нельзя просто опубликовать документ, и MongoDB обработает его автоматически, если уже существует документ, просто перезапишите его, иначе создайте новый документ?

Моя структура документа:

{
    "_id": "my unique id string",
    "name": "name1",
    "Address":{
       "street": "street 1",
       "country": "NZ",
    }
}

Я проверяю наличие документа, сравнивая поле «_id».


person user3243499    schedule 11.03.2018    source источник
comment
я думаю, это то, что вы ищете db.collection.findOneAndUpdate(filter, update, options)   -  person Alpit Anand    schedule 11.03.2018
comment
@AlpitAnand Я публикую контент через RESTHeart, а не через консоль Mongo. Итак, я не уверен, как выполнить ваше предложение.   -  person user3243499    schedule 11.03.2018


Ответы (3)


С RESTHeart все запросы на запись имеют upsert семантику: запрос вставляет документ в коллекцию (если он еще не существует) или обновляет его (если он существует).

Чтобы избежать обновления документа, если он уже существует, вы можете использовать ETag функция проверки RESTHeart.

Запрос с заголовком If-Match обновляет существующий документ, только если его свойство _etag соответствует указанному значению.

Следующий запрос завершается с ошибкой с кодом состояния 412 Precondition Failed, если документ /db/coll/docid существует:

POST /db/coll { "_id": "docid", "name": "name1", .. } If-Match:"etag"
person Andrea Di Cesare    schedule 15.03.2018

Вам нужно использовать фильтр, по которому вы найдете документ, затем найти и обновить документ. Используя драйвер Java, вы можете сделать это следующим образом:

Document filter = new Document("_id", "my unique id string");
Document update = new Document("name", "name1")
                     .append("Address", "<other fields>");
Document oldDocument = database
                     .getCollection("collectionName")
                     .findOneAndUpdate(filter, update);

oldDocument будет нулевым, если нет документа, соответствующего фильтру.

Если вы хотите вставить документ в случае, если он не существует, вам следует upsert:

UpdateOptions uo = new UpdateOptions().upsert(true);
database.getCollection("collectionName")
             .updateOne(filter, update, uo);

Последний вызов метода вернет объект результата, который даст вам новый ID, если документ был создан.

person ernest_k    schedule 11.03.2018

Если вы используете RESTHeart, то методы PUT и POST реализуют семантику upsert Mongodb. по умолчанию. См. раздел Запросы на запись в документы.

person mturatti    schedule 12.03.2018