【问题标题】:Spring Boot - Mongodb - Auto incremented field based on another fieldSpring Boot - Mongodb - 基于另一个字段的自动递增字段
【发布时间】:2019-10-05 06:44:17
【问题描述】:

我有一个包含以下数据的集合:

id: 1, item: book, version: 1
id: 2, item: book, version: 2
id: 3, item: cat, version: 1
id: 4, item: cat, version: 2
id: 5, item: cat, version: 3

我想通过提及项目本身来插入一个新元素。 id 当然是自动生成的。版本应根据项目字段自动递增。这意味着如果我想插入一个带有“书”项的新文档,它应该如下所示:

id: 6, item: book, version: 3

如何在 MongoDB 数据库中使用 Spring Boot。

情况: 实际上我有两个集合:变化,状态。在服务器端应用程序中,我们有业务。我们在每个企业的州集合中都有一份州文件。业务中可能存在数据更改,当发生更改时,我们从状态集合中获取业务状态。它包含一个businessID 和一个版本。版本是业务的整体数据版本。我们将版本号加一并将其保存到状态文档中。然后我们在更改集合中保存一个文档,其中包含一个新版本的 businessId 和有关实际更改的数据。 问题是这是数据库中的两个操作。如果业务发生了很多变化,那么这两个集合中的数据可能会损坏。计划是删除状态集合并仅保留更改集合。然后我们必须对单个数据库操作执行以下操作:在更改集合中找到一项业务的最大版本,然后在其中插入一个新文档,其中包含递增的版本号和新的更改。我不知道如何进行一次查找和插入操作

【问题讨论】:

    标签: java mongodb spring-boot


    【解决方案1】:

    您可以使用另一个集合来保存 id 序列。每次有人请求一个新的 id 时,该方法都会确保它增加 id。

    @Document
    public class CollectionSeq {
        @Id
        @Indexed( unique = true)
        private String collection;
        private long current = 1;
    }
    

    可以获取下一个id:

    public long next(String collection) {
            CollectionSeq next = operations.findAndModify(
                    query(where("collection").is(collection)),
                    new Update().inc("current", 1),
                    options().returnNew(true).upsert(true),
                    CollectionSeq.class
            );
            return Objects.requireNonNull(next).getCurrent();
    } 
    

    和之前保存集合的新文档分配id。

    Item item = new Item();
    item.setId(collectionSeqRepository.next("item"));
    item.setVersion(4);
    ...
    
    itemRepository.save(item)
    

    音序器集合如下所示:

    collection: item, current: 3
    collection: book, current: 100
    collection: version, current: 4
    

    根据官方文档,MongoDB 确实提供了独立的更新和返回。

    这里是 MongoDB 官方文档链接:Why findAndModify is Atomic.

    并发控制允许多个应用程序 并发运行而不会导致数据不一致或冲突。

    一种方法是在一个字段上创建一个唯一索引,该索引只能具有 独特的价值观。这可以防止插入或更新创建 重复数据。在多个字段上创建唯一索引以强制 字段值组合的唯一性。使用示例 情况,请参阅 update() 和 Unique Index 以及 findAndModify() 和 Unique 索引。

    另一种方法是指定字段的预期当前值 在写操作的查询谓词中。

    【讨论】:

    • 我做过类似的事情,但这会导致同步问题,这就是为什么我必须将所有内容保存在同一个集合中。 (我的意思是项目(数据)和版本)
    • 我更新了我的答案。你能分享一个复制同步问题的例子吗?
    • 其实我有两个集合:变化,状态。在服务器端应用程序中,我们有业务。我们在每个企业的州集合中都有一份州文件。业务中可能存在数据更改,当发生更改时,我们从状态集合中获取业务状态。它包含一个businessID 和一个版本。版本是业务的整体数据版本。我们将版本号加一并将其保存到状态文档中。然后我们在更改集合中保存一个文档,其中包含一个新版本的 businessId 和有关实际更改的数据
    • 问题是,这是数据库中的两个操作。如果业务发生了很多变化,那么这两个集合中的数据可能会损坏。计划是删除状态集合并仅保留更改集合。然后我们必须对单个数据库操作执行以下操作:在更改集合中找到一项业务的最大版本,然后在其中插入一个新文档,其中包含递增的版本号和新的更改。我不知道如何进行一次查找和插入操作。
    猜你喜欢
    • 1970-01-01
    • 2017-02-02
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 2019-07-17
    相关资源
    最近更新 更多