【问题标题】:How to use dynamic schema in spring data with mongodb?如何在带有 mongodb 的 spring 数据中使用动态模式?
【发布时间】:2016-06-21 04:55:49
【问题描述】:

mongodb是一个无模式的文档数据库,但是在spring data中,需要定义实体类和repository类,如下:

实体类:

@Document(collection = "users")
public class User implements UserDetails {
    @Id private String userId;
    @NotNull @Indexed(unique = true) private String username;
    @NotNull private String password;
    @NotNull private String name;
    @NotNull private String email;
}

存储库类:

public interface UserRepository extends MongoRepository<User, String> {
    User findByUsername(String username);
}

有没有办法在 spring data mongodb 中使用 map not class,以便服务器可以接受任何动态 JSON 数据,然后将其存储在 BSON 中而无需任何前类定义?

【问题讨论】:

    标签: spring-data-mongodb


    【解决方案1】:

    首先,一些关于无模式数据的有见地的链接:

    第二...有人可能想知道 Spring 或 Java 是否是解决您问题的正确解决方案 - 为什么不是更动态的工具,例如 Ruby、Python 或 Mongoshell?

    话虽如此,让我们专注于技术问题。

    如果您的目标只是存储随机数据,您基本上可以定义自己的控制器并直接使用 MongoDB Java 驱动程序。

    如果您真的坚持没有为您的域对象类预定义架构,请使用:

    @Document(collection = "users")
    public class User implements UserDetails {
        @Id
        private String id;
        private Map<String, Object> schemalessData;
    
        // getters/setters omitted
    }
    

    基本上,它为您提供了一个容器,您可以在其中放置您想要的任何内容,但要注意序列化/反序列化问题(如果嵌套文档中有 ObjectIds 和 DBRefs,这可能会变得很棘手)。此外,如果数据层次结构变得过于复杂,更新数据可能会变得很麻烦。

    不过,在某些时候,您会意识到您的数据确实具有可以精确定位并放入定义明确的 POJO 的架构。

    更新

    由于人们在 2020 年仍然碰巧阅读这篇文章,因此更新较晚:Jackson 注释 JsonAnyGetterJsonAnySetter 让您隐藏无模式数据容器的根,以便您的未知字段可以作为顶级字段发送在你的有效载荷中。它们仍将嵌套存储在您的 MongoDB 文档中,但在通过 Spring 请求资源时将显示为顶级字段。

    @Document(collection = "users")
    public class User implements UserDetails {
        @Id
        private String id;
    
        // add all other expected fields (getters/setters omitted)
        private String foo;
        private String bar;
    
        // a container for all unexpected fields
        private Map<String, Object> schemalessData;
    
        @JsonAnySetter
        public void add(String key, Object value) {
            if (null == schemalessData) {
                schemalessData = new HashMap<>();
            }
            schemalessData.put(key, value);
        }
    
        @JsonAnyGetter
        public Map<String, Object> get() {
            return schemalessData;
        }
    
        // getters/setters omitted
    }
    

    【讨论】:

    • 如何在 mongoDB 中将动态字段存储为顶级?
    • 我的回答的核心是,对于 Spring Data,你不需要,因为这不是 Spring Data 的设计目的。要将“动态”字段存储为顶层,您需要定义自己的控制器并直接使用 mongo java 驱动程序,忽略 Spring Data 带来的所有自动魔术。
    猜你喜欢
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多