如何在 spring 数据中使用 mongodb 的动态模式?
How to use dynamic schema in spring data with mongodb?
Mongodb是一个no-schema文档数据库,但是在spring数据中,需要定义实体class和存储库class,如下:
实体class:
@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;
}
存储库class:
public interface UserRepository extends MongoRepository<User, String> {
User findByUsername(String username);
}
是否可以在 spring 数据 mongodb 中使用 map 而不是 class 以便服务器可以接受任何动态 JSON 数据然后将其存储在 BSON 中而无需任何pre-class定义?
首先,一些关于无模式数据的有见地的链接:
其次...有人可能想知道 Spring 或 Java 是否是您问题的正确解决方案 - 为什么不是更动态的工具,例如 Ruby,Python 还是 Mongoshell?
话虽如此,让我们关注技术问题。
如果您的目标只是存储随机数据,您基本上可以定义自己的控制器并直接使用 MongoDB Java 驱动程序。
如果您真的坚持没有为您的域对象预定义架构 class,请使用此:
@Document(collection = "users")
public class User implements UserDetails {
@Id
private String id;
private Map<String, Object> schemalessData;
// getters/setters omitted
}
基本上它为您提供了一个容器,您可以在其中放置任何您想要的东西,但要注意 serialization/deserialization 问题(如果您的嵌套文档中有 ObjectId 和 DBRef,这可能会变得棘手)。此外,如果您的数据层次结构变得过于复杂,更新数据可能会变得令人讨厌。
不过,在某些时候,您会意识到您的数据确实有一个可以精确定位并放入定义明确的 POJO 中的模式。
更新
延迟更新,因为人们在 2020 年仍然碰巧阅读此 post:Jackson 注释 JsonAnyGetter and JsonAnySetter 让您隐藏无模式数据容器的根,以便您的未知字段可以作为有效载荷中的顶级字段。它们仍将嵌套存储在您的 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是一个no-schema文档数据库,但是在spring数据中,需要定义实体class和存储库class,如下:
实体class:
@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;
}
存储库class:
public interface UserRepository extends MongoRepository<User, String> {
User findByUsername(String username);
}
是否可以在 spring 数据 mongodb 中使用 map 而不是 class 以便服务器可以接受任何动态 JSON 数据然后将其存储在 BSON 中而无需任何pre-class定义?
首先,一些关于无模式数据的有见地的链接:
其次...有人可能想知道 Spring 或 Java 是否是您问题的正确解决方案 - 为什么不是更动态的工具,例如 Ruby,Python 还是 Mongoshell?
话虽如此,让我们关注技术问题。
如果您的目标只是存储随机数据,您基本上可以定义自己的控制器并直接使用 MongoDB Java 驱动程序。
如果您真的坚持没有为您的域对象预定义架构 class,请使用此:
@Document(collection = "users")
public class User implements UserDetails {
@Id
private String id;
private Map<String, Object> schemalessData;
// getters/setters omitted
}
基本上它为您提供了一个容器,您可以在其中放置任何您想要的东西,但要注意 serialization/deserialization 问题(如果您的嵌套文档中有 ObjectId 和 DBRef,这可能会变得棘手)。此外,如果您的数据层次结构变得过于复杂,更新数据可能会变得令人讨厌。
不过,在某些时候,您会意识到您的数据确实有一个可以精确定位并放入定义明确的 POJO 中的模式。
更新
延迟更新,因为人们在 2020 年仍然碰巧阅读此 post:Jackson 注释 JsonAnyGetter and JsonAnySetter 让您隐藏无模式数据容器的根,以便您的未知字段可以作为有效载荷中的顶级字段。它们仍将嵌套存储在您的 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
}