MongoDB嵌入式对象没有ID(空值)

我对使用Spring Data的MongoDB有疑问。 我有这些域类:

@Document public class Deal { @Id private ObjectId _id; private Location location; private User user; private String description; private String title; private String price; private boolean approved; private Date expirationDate; private Date publishedDate; } @Document public class Location { @Id private ObjectId _id; private Double latitude; private Double longitude; private String country; private String street; private String zip; } @Document public class User { @Id private ObjectId _id; private String email; private String password; private String profile_image_url; private Collection deals = new ArrayList(); } 

通过这些域名,我可以成功地进行CRUD。 只有一个问题。 保存具有交易的用户时,将交易和位置在将它们保存到MongoDB时将其设置为空。 为什么MongoDB不能为嵌入对象生成唯一的id?

用一笔交易保存用户后的结果:

 { "_id" : ObjectId( "4fed0591d17011868cf9c982" ), "_class" : "User", "email" : "milo@gmail.com", "password" : "mimi", "deals" : [ { "_id" : null, "location" : { "_id" : null, "latitude" : 2.22, "longitude" : 3.23445, "country" : "Denmark", "street" : "Denmark road 77", "zip" : "2933" }, "description" : "The new Nexus 7 Tablet. A 7 inch tablet from Google.", "title" : "Nexus 7", "price" : "1300", "approved" : false, "expirationDate" : Date( 1343512800000 ), "publishedDate" : Date( 1340933521374 ) } ] } 

从结果中可以看出,Deal和Location ID设置为NULL。

MongoDB CRUD操作( insertupdatefindremove )都专门在顶级文档上运行 – 当然,您可以按嵌入文档中的字段进行过滤。 嵌入的文档始终在父文档中返回。

_id字段是父文档的必填字段,通常不是必需的或存在于嵌入文档中。 如果您需要唯一标识符,您当然可以创建它们,如果方便您的代码或心智模型,您可以使用_id字段来存储它们; 更典型的是,它们以它们代表的名称命名(例如“username”,“otherSystemKey”等)。 除顶级文档外,MongoDB本身和任何驱动程序都不会自动填充_id字段。

特别是在Java中,如果要为嵌入式文档中的_id字段生成ObjectId值,可以使用以下命令:

 someEmbeddedDoc._id = new ObjectId(); 

默认情况下,仅在根docuemnts上没有在子文档上设置_id。

您需要在插入和更新时为子文档定义_id。

Mongo不会在嵌入式文档上创建或需要_id 。 你可以添加一个_id字段 – 我已经完成了。

 @Document public class Location { @Id private ObjectId _id; public Location() { this._id = ObjectId.get(); } } @Document public class User { @Id private ObjectId _id; public User() { this._id = ObjectId.get(); } } 

这对我很有用。

在REST体系结构的上下文中,嵌套文档具有自己的ID是很有意义的。

  1. 持久性实现应独立于资源表示。 作为API使用者,我不在乎您是否使用mongo或mysql。 如果你在mongo中没有id的嵌套文档,试着想象如何将持久层更改为关系数据库。 现在进行相同的练习,事先考虑一个独立于实现的方法。 在关系数据库,根和嵌套文档中对嵌套文档建模将是不同的实体/表,每个实体/表都有自己的ID。 根可以与嵌套文档具有一对多的关系。
  2. 我可能需要直接访问嵌套文档而不是顺序访问。我可能不需要绝对唯一ID,如mongo发布的那些,但我仍然需要一些本地唯一标识符。 这在根文档中是唯一的。

在讨论了嵌套文档中对id的需求之后我已经提出了一个问题@dcrosta已经给出了关于如何在mongo中填充_id字段的正确答案。

希望这可以帮助。