簡體   English   中英

MongoDB 嵌入式對象沒有 ID(空值)

[英]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 操作( insertupdatefindremove )都專門對頂級文檔進行操作——當然,您可以按嵌入文檔中的字段進行過濾。 嵌入的文檔總是在父文檔中返回。

_id字段是父文檔的必填字段,通常不需要或出現在嵌入的文檔中。 如果你需要一個唯一的標識符,你當然可以創建它們,如果你的代碼或你的心智模型方便的話,你可以使用_id字段來存儲它們; 更典型的是,它們以它們所代表的名稱命名(例如“用戶名”、“otherSystemKey”等)。 除了頂級文檔之外,MongoDB 本身和任何驅動程序都不會自動填充_id字段。

特別是在 Java 中,如果您希望為嵌入文檔中的_id字段生成 ObjectId 值,您可以這樣做:

someEmbeddedDoc._id = new ObjectId();

在 REST 架構的上下文中,嵌套文檔有自己的 ID 是完全合理的。

  1. 持久性實現應該獨立於資源表示。 作為 API 使用者,我不在乎您使用的是 mongo 還是 mysql。 如果您在 mongo 中嵌套沒有 id 的文檔,請嘗試想象如何將持久層更改為關系數據庫。 現在使用與實現無關的方法預先考慮過相同的練習。 在關系數據庫中建模嵌套文檔,根和嵌套文檔將是不同的實體/表,每個實體/表都有自己的 ID。 根可以與嵌套文檔有一對多的關系。
  2. 我可能需要直接訪問嵌套文檔,而不是按順序訪問。我可能不需要絕對唯一 ID,例如 mongo 發布的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM