1。概要
場合によっては、MongoDBデータベースに挿入したばかりのドキュメントのIDが必要になります。たとえば、IDを呼び出し元への応答として返送したり、作成したオブジェクトをデバッグ用にログに記録したりすることができます。
このチュートリアルでは、MongoDBでIDがどのように実装されているか、およびJavaプログラムを介してコレクションに挿入したばかりのドキュメントのIDを取得する方法を確認します。
2。 MongoDBドキュメントのIDは何ですか?
すべてのデータストレージシステムと同様に、MongoDBには、コレクションに保存されているドキュメントごとに一意の識別子が必要です。この識別子は、リレーショナルデータベースの主キーに相当します。
MongoDBでは、このIDは12バイトで構成されています:
- 4バイトのタイムスタンプ値は、Unixエポックからの秒数を表します
- プロセスごとに1回生成される5バイトのランダム値。このランダムな値は、マシンとプロセスに固有です。
- 3バイトのインクリメントカウンター
IDは_idという名前のフィールドに保存されます クライアントによって生成されます。 これは、ドキュメントをデータベースに送信する前にIDを生成する必要があることを意味します。クライアント側では、ドライバーで生成されたIDを使用するか、カスタムIDを生成することができます。
同じクライアントによって同じ秒で作成されたドキュメントには、最初の9バイトが共通していることがわかります。したがって、この場合、IDの一意性はカウンターに依存します。カウンターを使用すると、クライアントは同じ秒で1,600万を超えるドキュメントを作成できます。
タイムスタンプで始まりますが、識別子がソート基準として使用されないように注意する必要があります。これは、カウンターが単調であることが保証されていないため、同じ秒で作成されたドキュメントが作成日でソートされることが保証されていないためです。また、クライアントごとにシステムクロックが異なる場合があります。
Javaドライバーは、カウンターに乱数ジェネレーターを使用しますが、これは単調ではありません。そのため、作成日で並べ替えるためにドライバーが生成したIDを使用しないでください。
3。 ObjectId クラス
一意の識別子はObjectIdに保存されます IDに格納されているデータを手動で解析せずに取得するための便利なメソッドを提供するクラス。
たとえば、IDの作成日を取得する方法は次のとおりです。
Date creationDate = objectId.getDate();
同様に、IDのタイムスタンプを秒単位で取得できます:
int timestamp = objectId.getTimestamp();
ObjectId classは、カウンター、マシンID、またはプロセスIDを取得するメソッドも提供しますが、これらはすべて非推奨です。
4。 IDの取得
覚えておくべき主なことは、MongoDBでは、クライアントがドキュメントの一意の識別子を生成することです。 クラスタに送信する前に。これは、リレーショナルデータベースのシーケンスとは対照的です。これにより、このIDの取得が非常に簡単になります。
4.1。ドライバーが生成したID
ドキュメントの一意のIDを生成するための標準的で簡単な方法 ドライバーに仕事を任せることです。 新しいドキュメントを挿入するとき コレクションへ 、 _idがない場合 ドキュメントにフィールドが存在します 、ドライバーは新しい ObjectIdを生成します 挿入コマンドをクラスターに送信する前。
新しいドキュメントを挿入するためのコード コレクションに入れると、次のようになります:
Document document = new Document();
document.put("name", "Shubham");
document.put("company", "Baeldung");
collection.insertOne(document);
IDの生成方法を示すことは決してないことがわかります。
insertOne()の場合 メソッドが戻ると、生成された ObjectIdを取得できます ドキュメントから :
ObjectId objectId = document.getObjectId("_id");
ObjectIdを取得することもできます ドキュメントの標準フィールドのように 次に、それを ObjectId にキャストします :
ObjectId oId = (ObjectId) document.get("_id");
4.2。カスタムID
IDを取得するもう1つの方法は、コードでIDを生成し、ドキュメントに配置することです。 他の分野と同じように。 ドキュメントを送信する場合 _idを使用 ドライバーへのフィールドでは、新しいフィールドは生成されません。
MongoDB Document のIDが必要な場合は、これが必要になることがあります。 ドキュメントを挿入する前 コレクション 。
新しいObjectIdを生成できます クラスの新しいインスタンスを作成することによって:
ObjectId generatedId = new ObjectId();
または、静的な get()を呼び出すこともできます。 ObjectIdのメソッド クラス:
ObjectId generatedId = ObjectId.get();
次に、ドキュメントを作成するだけです。 生成されたIDを使用します。そのために、ドキュメントで提供できます。 コンストラクター:
Document document = new Document("_id", generatedId);
または、 put()を使用することもできます 方法:
document.put("_id", generatedId);
ユーザー生成IDを使用する場合、新しい ObjectIdを生成する場合は注意が必要です。 IDの重複は禁止されているため、各挿入の前に。 IDが重複すると、 MongoWriteExceptionが発生します キーメッセージが重複しています。
ObjectId クラスは、識別子の一部を設定できるようにする他のいくつかのコンストラクターを提供します。
public ObjectId(final Date date)
public ObjectId(final Date date, final int counter)
public ObjectId(final int timestamp, final int counter)
public ObjectId(final String hexString)
public ObjectId(final byte[] bytes)
public ObjectId(final ByteBuffer buffer)
ただし、ドライバーに提供されるIDの一意性はコードに完全に依存しているため、これらのコンストラクターを使用する場合は十分に注意する必要があります。これらの特定のケースでは、重複キーエラーが発生する可能性があります:
- 同じ日付(またはタイムスタンプ)とカウンターコンボを複数回使用する場合
- 同じ16進数の文字列を使用する場合 、バイト 配列、または ByteBuffer 数回