gpt4 book ai didi

java - MongoDB 和多个 upsert

转载 作者:可可西里 更新时间:2023-11-01 09:36:46 25 4
gpt4 key购买 nike

我对 MongoDB 比较陌生,但我们考虑将其用作遗留服务前面的某种缓存。在这种情况下,我们偶然发现了一些问题。

首先,一些解释。

此缓存服务将位于遗留服务和客户端之间。客户端将连接到缓存服务,该服务从遗留服务获取数据。缓存服务每 X 分钟获取一次数据,并将它们保存在 MongoDB 中。该模式真的非常简单:只是一个包含大量键/值的文档。没有嵌套文档等。此外,我们将 _id 设置为来自遗留服务的唯一 ID,因此我们也可以控制它。

当缓存服务从遗留服务中获取数据时,它只会得到一个增量(仅自上次获取以来发生变化)。因此,如果自上次以来有 5 个“对象”发生了变化,您只会得到这 5 个“对象”(但是您得到的是完整的对象,而不是对象的增量)。如果任何新的“对象”已添加到遗留服务中,那么这些对象当然也在增量中。

我们的“问题”

在我看来,这听起来像是一个增补。如果有新对象,则插入它们。如果现有对象发生更改,请更新它们。然而,MongoDB 似乎并不特别喜欢多重更新插入。只是插入给我一个关于重复键的错误,这是完全可以理解的,因为已经存在具有相同 _id 的文档。可以采用 upsert 参数的更新函数不能采用新对象列表。在我看来,单个查询是不可能的。不过,我可能完全忽略了这里的某些内容。

可能的解决方案

有许多不同的解决方案,我特别想到了两个:

  • 执行两个查询:首先,计算一个包含所有 _id 的列表(请记住,我们从旧服务中获得了这些)。然后,使用 $in 函数和 _id 列表删除它们并立即插入新文档。这实际上应该用新数据更新我们的集合。它也很容易实现。可能出现的问题是客户端在删除和插入之间请求数据,因此错误地得到空结果。这是一个交易破坏者,绝对不能发生。
  • 对每个更改的对象执行一次更新插入。也很容易实现,并且不会出现与其他解决方案相同的问题。不过,这还有其他(可能是想象中的)问题。它可以在短时间内处理多少个 upserts?它能很容易地每分钟处理 5000 个更新插入吗?这些不是大文档,只有大约 20 个键/值,没有子文档。这个数字是凭空得出的,实际数字很难预测。在我看来,这种方法感觉不对。我不明白为什么每个新文档都需要运行一个查询。

任何帮助将不胜感激,无论是关于两个提议的解决方案还是任何其他解决方案。作为旁注,技术并不是真正可以讨论的,所以请不要建议其他类型的数据库或语言。我们选择我们所选择的东西还有其他强有力的原因:)

最佳答案

或者如果您的 key 是复合 key ,您可以使用:

public static BulkWriteResult insertAll(MongoCollection<Document> coll, List<Document> docs, String[] keyTags, boolean upsert) {
if(docs.isEmpty())
return null;
List<UpdateOneModel<Document>> requests = new ArrayList<>(docs.size());
UpdateOptions opt = new UpdateOptions().upsert(upsert);
for (Document doc : docs ) {
BasicDBObject filter = new BasicDBObject();
for (String keyTag : keyTags) {
filter.append(keyTag, doc.get(keyTag));
}
BasicDBObject action = new BasicDBObject("$set", doc);
requests.add(new UpdateOneModel<Document>(filter, action, opt));
}
return coll.bulkWrite(requests);
}

关于java - MongoDB 和多个 upsert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19694006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com