【问题标题】:Updating element in array inside document with MongoDB not preserving its type使用MongoDB更新文档内数组中的元素不保留其类型
【发布时间】:2026-01-02 05:45:01
【问题描述】:

在我的项目中有这样的结构:

class User {
  private List<MapObject> mapObjects;
}

class MapObject {
  ... some fields...
}

class SubMapObject {
  ... some additional fields
}

最初,User 类从模板中填充数据(还包括 SubMapObject 类的实例),并通过 Spring 集成中的 MongoTemplate 存储在 MongoDB 中,如下所示:

mongoOps.insert(u);

并且mapObjects字段中的每一个条目的信息都被保留了,_class的信息也是如此。 (如果它是子类)

然后,我们需要更新 User 的 mapObjects 字段中的单个元素。我们这样做:

mongoOps.updateFirst(
                query(where("_id").is(userObjectId).and("mapObjects._id")
                        .is(mo.get_id())), update("mapObjects.$", mo),
                User.class);

例如,mo 是 SubMapObject。

每当传递任何子类(MapObject)实例时,该对象的 MongoDB 记录中有关它是什么类(_class)字段的信息都会丢失,它被视为其父类 - MapObject。所以我们有以下问题:)

1) 我们哪里做错了,如何保存这个对象类的信息?

2) 此外,我们想知道更新整个 mapObjects 字段是否比仅更新其中的特定元素更快(因为在这种情况下它必须迭代才能找到它)。一个用户很可能在其 mapObjects 列表中有 300-400 个条目。

【问题讨论】:

  • 看到与自定义推送实现相同的问题。奇怪的是对象的字段是使用自定义转换器映射的,但对象本身并没有保留 _class 字段。

标签: java mongodb database


【解决方案1】:

我刚刚遇到了这个问题并管理了一个解决方案。我假设您也在使用 Spring Data for MongoDB Repository 接口,如果是这样,请在此处查看此相关问题:How would I do $push using MongoRepository in Spring Data? 了解更多详细信息。

基本思想是,一旦您为您的存储库连接了自定义类,那么最后一步就是使用从您的上下文中注入 mongo 映射转换器。然后,与其传递您的对象,不如先将其转换为 DBObject 并保存该 DBObject。转换器应该按预期写出一个 _class 字段。

【讨论】: