gpt4 book ai didi

java - 与 Mongo 的版本化对象/JSON 映射?

转载 作者:IT老高 更新时间:2023-10-28 13:33:55 27 4
gpt4 key购买 nike

所以我有一个需要存储某些配置信息的应用程序,因此我计划将配置存储为 Mongo 中的简单 JSON 文档:

appConfig: {
fizz: true,
buzz: 34
}

这可能会映射到 Java POJO/实体,例如:

public class AppConfig {
private boolean fizz;
private int buzz;
}

等等。通常,对于关系数据库,我使用 Hibernate/JPA 进行从表数据到 Java 实体的 O/R 映射。我相信最接近 table/Hibernate 的 JSON/Mongo 伴侣是 Morphia/GSON 组合:使用 Morphia 驱动从我的 Java 应用程序到 Mongo 的连接,然后使用 GSON 到 O/J 将 JSON 映射到/来自 Java POJO/实体。

这里的问题是,随着时间的推移,我的 appConfig 文档结构会发生变化。可能很简单,例如:

appConfig: {
fizz: true,
buzz: 34
foo: "Hello!"
}

这需要 POJO/实体变成:

public class AppConfig {
private boolean fizz;
private int buzz;
private String foo;
}

但问题是我可能有数以万计的 JSON 文档已经存储在 Mongo 中,其中没有 foo 属性。在这种特定情况下,显而易见的解决方案是在属性上设置一个默认值,例如:

public class AppConfig {
private boolean fizz;
private int buzz;
private String foo = "Hello!"
}

但实际上,AppConfig 文档/模式/结构最终可能会发生如此大的变化,以至于它在任何方面、形状或形式都不像其原始设计。但关键是:我需要向后兼容,并且最好能够更新/转换文档以在适当的情况下匹配新的架构/结构。

我的问题:这个“版本化文档”问题通常是如何解决的?

最佳答案

我通常通过为集合中的每个文档添加一个版本字段来解决这个问题。

AppConfig 集合中可能有多个文档:

{
_id: 1,
fizz: true,
buzz: 34
}

{
_id: 2,
version: 1,
fizz: false,
buzz: 36,
foo: "Hello!"
}

{
_id: 3,
version: 1,
fizz: true,
buzz: 42,
foo: "Goodbye"
}

在上面的示例中,版本 1 有两个文档,版本 0 有一个旧文档(在此模式中,我通常将缺失或空版本字段解释为版本 0,因为我总是只添加一次'm 通过生产中的文档进行版本控制)。

这种模式的两个原则:

  1. 文档在实际修改时始终保存为最新版本。
  2. 读取文档时,如果它不是最新版本,则会透明地升级到最新版本。

您可以通过检查版本字段并在版本不够新时执行迁移来做到这一点:

DBObject update(DBObject document) {
if (document.getInt("version", 0) < 1) {
document.put("foo", "Hello!"); //add default value for foo
document.put("version", 1);
}
return document;
}

此迁移可以相当轻松地添加具有默认值的字段、重命名字段和删除字段。由于它位于应用程序代码中,因此您可以根据需要进行更复杂的计算。

文档迁移后,您可以通过任何您喜欢的 ODM 解决方案运行它,将其转换为 Java 对象。该解决方案不再需要担心版本控制,因为它处理的文档都是最新的!

对于 Morphia,这可以使用 @PreLoad 来完成。注释。

两个警告:

  1. 有时您可能希望立即将升级后的文档保存回数据库。最常见的原因是迁移成本高昂、迁移不确定或与其他数据库集成,或者您急于升级旧版本。

  2. 添加或重命名用作查询条件的字段有点棘手。在实践中,您可能需要执行多个查询,并统一结果。

在我看来,这种模式突出了 MongoDB 的一大优势:由于文档在应用程序中进行了版本控制,因此您可以在应用程序中无缝迁移数据表示,而无需像使用 SQL 那样需要任何离线“迁移阶段”数据库。

关于java - 与 Mongo 的版本化对象/JSON 映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24521718/

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