如何在MongoDB中放置现有记录以便不创建新文档?

时间:2018-03-11 07:26:55

标签: mongodb restheart

如何有效地将文档发布到MongoDB,而不检查它是否已经在集合中。目前,在我的JAVA代码中,我首先检查文档的存在,然后如果它不是我发布的位置。这似乎非常慢,因为对于每个文档我都会发出两个查询。

是否可以发布文档,MongoDB会自动处理它,如果已有文档,只需覆盖它,否则创建一个新文档?

我的文档结构:

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

我通过比较" _id"来检查文档的存在。字段。

3 个答案:

答案 0 :(得分:1)

使用RESTHeart,所有写入请求都有 upsert semantic :请求将文档插入集合(如果它尚不存在)或更新它(如果存在)。

为了避免文档已经存在,您可以使用RESTHeart的ETag检查功能。

使用 If-Match 标头的请求仅在其 _etag 属性与指定值匹配时才更新现有文档。

如果文档/db/coll/docid存在,则以下请求将失败并显示 412 Precondition Failed 状态代码:

POST /db/coll { "_id": "docid", "name": "name1", .. } If-Match:"etag"

答案 1 :(得分:0)

您需要使用用于查找文档的过滤器,然后查找并更新文档。使用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

答案 2 :(得分:0)

如果您正在使用RESTHeart,那么PUT和POST方法默认实现Mongodb's upsert semantics。请参阅文档中的Write Requests部分。