web-dev-qa-db-ja.com

MongoDB埋め込みオブジェクトにはIDがありません(null値)

MongoDB with Spring Dataについて質問があります。私はこれらのドメインクラスを持っています:

@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を正常に実行できます。問題は1つだけです。取引を含むユーザーを保存する場合、取引と場所はMongoDBに保存するときに_idがnullに設定されます。 MongoDBが埋め込みオブジェクトの一意のIDを生成できないのはなぜですか?

1つの取引でユーザーを保存した後の結果:

{ "_id" : ObjectId( "4fed0591d17011868cf9c982" ),
  "_class" : "User",
  "email" : "[email protected]",
  "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に設定されています。

25
Millad

MongoDB CRUD操作(insertupdatefindremove)はすべてトップレベルのドキュメントのみを操作します-もちろん、フィールドでフィルタリングすることもできます埋め込みドキュメント内。埋め込みドキュメントは常に親ドキュメント内で返されます。

_idフィールドは、親ドキュメントの必須フィールドであり、通常は不要であるか、埋め込みドキュメントには存在しません。一意の識別子が必要な場合は、それらを確実に作成できます。コードまたはメンタルモデルにとって便利な場合は、_idフィールドを使用してそれらを格納できます。より一般的には、それらが表すものにちなんで名前が付けられます(「username」、「otherSystemKey」など)。 MongoDB自体もドライバーも、最上位のドキュメントを除いて、_idフィールドに自動的に入力されません。

特にJavaでは、埋め込みドキュメントの_idフィールドのObjectId値を生成したい場合は、次のようにします。

someEmbeddedDoc._id = new ObjectId();
39
dcrosta

_idは、デフォルトではルートドキュメントにのみサブドキュメントに設定されません。

挿入および更新時にサブドキュメントの_idを定義する必要があります。

6
Sammaye

RESTアーキテクチャのコンテキストでは、ネストされたドキュメントが独自のIDを持っていることはすべての理にかなっています。

  1. 永続性の実装は、リソースの表現から独立している必要があります。 APIコンシューマーとして、mongoまたはmysqlを使用しているかどうかは気にしません。 mongoでidなしでドキュメントをネストする場合は、永続化レイヤーをリレーショナルデータベースに変更する方法を想像してみてください。ここで、実装に依存しないアプローチで事前に考えていたのと同じ演習を行います。リレーショナルデータベースでのネストされたドキュメントのモデル化、ルート、およびネストされたドキュメントは、それぞれ独自のIDを持つ異なるエンティティ/テーブルになります。ルートは、ネストされたドキュメントと1対多の関係を持つことができます。
  2. ネストされたドキュメントに順次ではなく直接アクセスする必要がある場合があります.mongoによって発行されたような絶対一意のIDは必要ない場合がありますが、それでもローカルの一意の識別子が必要です。これは、ルートドキュメント内で一意です。

ネストされたドキュメントでのIDの必要性について私の主張を論じた@dcrostaは、mongoの_idフィールドに値を設定する方法について正しい答えをすでに提供しています。

お役に立てれば。

5
Daniel Cerecedo

Mongoは、埋め込みドキュメントで_idsを作成または必要としません。必要に応じて、_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();
    }
}

これは私にとってはうまくいきます。

5
sbzoom