0

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

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

我的文档结构:

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

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

4

3 回答 3

1

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

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

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

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

POST /db/coll { "_id": "docid", "name": "name1", .. } If-Match:"etag"
于 2018-03-15T22:14:31.757 回答
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如果没有文档与过滤器匹配,则将为 null 。

如果您想插入文档以防它不存在,那么您应该upsert

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

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

于 2018-03-11T08:23:44.623 回答
0

如果您使用的是 RESTHeart,那么 PUT 和 POST 方法默认实现Mongodb 的 upsert 语义。请参阅文档中的写入请求部分。

于 2018-03-12T09:04:48.927 回答