如何将现有记录放入 MongoDB 以便不创建新文档?

How to put an existing record in the MongoDB so that no new document is created?

如何在不检查文档是否已在集合中的情况下有效地将文档 post 到 MongoDB。目前,在我的 JAVA 代码中,我首先检查文档是否存在,然后如果它不在我 post 的位置。这似乎很慢,因为我对每个文档都放置了两个查询。

难道不能只 post 文档并 MongoDB 自动处理它吗?如果已经有一个现有文档,只需覆盖它,否则创建一个新文档?

我的文档结构:

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

我正在通过比较“_id”字段来检查文档是否存在。

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

如果文档已创建,最后一个方法调用将 return 一个结果对象,它将为您提供新的 ID

如果您使用的是 RESTHeart,则 PUT 和 POST 方法会实现文档中的 Mongodb's upsert semantics by default. See the Write Requests 部分。

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

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

带有 If-Match header 的请求仅在其 _etag 属性匹配指定值。

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

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