[英]MongoDB Embedded Objects have no ID (null value)
我有一個關於帶有 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<Deal> deals = new ArrayList<Deal>();
}
有了這些域,我就可以成功地 CRUD。 只有一個問題。 保存帶有交易的用戶時,交易和位置在將它們保存到 MongoDB 時將 _id 設置為 null。 為什么 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 操作( insert
、 update
、 find
、 remove
)都專門對頂級文檔進行操作——當然,您可以按嵌入文檔中的字段進行過濾。 嵌入的文檔總是在父文檔中返回。
_id
字段是父文檔的必填字段,通常不需要或出現在嵌入的文檔中。 如果你需要一個唯一的標識符,你當然可以創建它們,如果你的代碼或你的心智模型方便的話,你可以使用_id
字段來存儲它們; 更典型的是,它們以它們所代表的名稱命名(例如“用戶名”、“otherSystemKey”等)。 除了頂級文檔之外,MongoDB 本身和任何驅動程序都不會自動填充_id
字段。
特別是在 Java 中,如果您希望為嵌入文檔中的_id
字段生成 ObjectId 值,您可以這樣做:
someEmbeddedDoc._id = new ObjectId();
在 REST 架構的上下文中,嵌套文檔有自己的 ID 是完全合理的。
在爭論了我關於嵌套文檔中需要 id 的觀點之后,@dcrosta 已經給出了關於如何在 mongo 中填充 _id 字段的正確答案。
希望這可以幫助。
默認情況下,僅在根文檔上未在子文檔上設置 _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();
}
}
這對我很有用。
其他答案現在不再適用。 每個子文檔都會自動獲得一個_id
。 實際上,為了避免將_id
應用於子文檔,您必須顯式傳遞選項
{ _id: false }
在子文檔架構中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.