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

2022-01-18 00:00:00 mongodb spring java spring-data

我有一个关于 MongoDB 和 Spring Data 的问题.我有这些域类:

I have a question regarding MongoDB with Spring Data. I have these domain classes:

@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<Deal> deals = new ArrayList<Deal>();
}

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

With these domains I can successfully CRUD. There is only one problem. When saving a User with Deals, the deals and Location get _id set to null when saving them to MongoDB. Why can´t MongoDB generate unique id´s for embedded objects?

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

The result after saving a User with one deal:

{ "_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 ) } ] }

从结果中可以看出,交易和位置 ID 设置为 NULL.

As you can see from the result, Deal and Location ID is set to NULL.

推荐答案

MongoDB CRUD 操作(insertupdatefindremove) 都只对顶级文档进行操作——当然您可以按嵌入文档中的字段进行过滤.嵌入文档总是在父文档中返回.

MongoDB CRUD operations (insert, update, find, remove) all operate on top-level documents exclusively -- although of course you can filter by fields in embedded documents. Embedded documents are always returned within the parent document.

_id 字段是父文档的必填字段,通常不需要或不存在于嵌入文档中.如果你需要一个唯一的标识符,你当然可以创建它们,并且你可以使用 _id 字段来存储它们,如果这对你的代码或你的心智模型来说很方便的话;更典型的是,它们以它们所代表的内容命名(例如用户名"、其他系统密钥"等).MongoDB 本身和任何驱动程序都不会自动填充 _id 字段,顶级文档除外.

The _id field is a required field of the parent document, and is typically not necessary or present in embedded documents. If you require a unique identifier, you can certainly create them, and you may use the _id field to store them if that is convenient for your code or your mental model; more typically, they are named after what they represent (e.g. "username", "otherSystemKey", etc). Neither MongoDB itself, nor any of the drivers will automatically populate an _id field except on the top-level document.

特别是在 Java 中,如果您希望为嵌入文档中的 _id 字段生成 ObjectId 值,您可以这样做:

Specifically in Java, if you wish to generate ObjectId values for the _id field in embedded documents, you can do so with:

someEmbeddedDoc._id = new ObjectId();

相关文章