23

java/morphia を使用して mongodb を処理しています。デフォルトの ObjectId は、Java レイヤーから使用するにはあまり便利ではありません。ObjectId を使用したキー生成プロセスを維持しながら、String 型にしたいと考えています_id = new ObjectId.toString()

この方法で副作用があるかどうか知りたいですか?たとえば、データベースのパフォーマンスに影響を与えたり、何らかの方法でキーの競合を引き起こしたりしますか? シャーディング環境に影響はありますか...

4

5 に答える 5

28

フィールドには任意のタイプの値を使用できます_id(配列を除く)。ObjectId を使用しないことを選択した場合は、何らかの方法で値の一意性を保証する必要があります (ObjectId を文字列にキャストすることで十分です)。重複したキーを挿入しようとすると、エラーが発生するため、対処する必要があります。

同じ _id を持つ 2 つのドキュメントを異なるシャードに挿入しようとすると、シャード クラスターにどのような影響があるかわかりません。挿入できると思いますが、後で噛まれます。(これをテストする必要があります)。

とはいえ、問題はないはず_id = (new ObjectId).toString()です。

于 2012-06-18T20:24:54.707 に答える
5

ObjectId を JSON に変換する際に問題があったため、実際に同じことをしました。

私はそれから次のようなことをしました

@Id
private String id;
public String getId() {
    return id();
}
public void setId(String id) {
    this.id = id;
}

そして、以前に挿入されたドキュメントを更新することを決定するまで、すべてが正常に機能し、ID でオブジェクトを取得して JSON 経由でページに送信し、JSON ポストによって同じ更新されたオブジェクトを受信し、代わりにデータストアから保存機能を使用しました。以前のデータを更新すると、既存のドキュメントを更新する代わりに、新しいドキュメントが挿入されました。

最悪の場合、新しいドキュメントは以前に挿入されたものと同じ ID を持っていました。これは不可能だと思いました。

とにかく、プライベートオブジェクトを ObjectID として設定し、get set を文字列として残したところ、期待どおりに機能しましたが、それがあなたのケースの考えに役立つかどうかはわかりません。

@Id
private ObjectId id;
public String getId() {
    return id.toString();
}
public void setId(String id) {
    this.id = new ObjectId(id);
}
于 2014-01-19T17:34:40.360 に答える
4

はい、_id として文字列を使用できます。

当然、適切な一意のキーである値が (ドキュメント内に) ある場合にのみお勧めします。このデザインは、"xxxxyyyy" という形式の文字列ジオタグが含まれる 1 つのコレクションで使用しました。このドキュメントごとに一意のフィールドは、ドキュメント内に存在する必要があり、そのにインデックスを作成する必要がありました...では、それをキーとして使用しないのはなぜですか? (これにより、余分なキーと値のペアが 1 つ回避され、さらに、MongoDB は "_id" でインデックスを自然に構築するため、コレクションの 2 つ目のインデックスも回避されました。コレクションのサイズを考えると、これらの両方が合計されて、かなりのスペースの節約になります。)

ただし、質問の口調から (「ObjectID はあまり便利ではありません」)、文字列を使用したい唯一の理由が、ObjectID をきちんと管理する方法を考え出すことに煩わされたくないということであれば... d は、それらについて理解するのに時間をかける価値があることを示唆しています。私は彼らが問題ではないと確信しています...あなたが彼らとの問題を理解したら.

そうでなければ:あなたの選択肢は何ですか?今後、MongoDB を使用するたびに文字列 ID を作成しますか?

于 2016-02-02T18:12:38.187 に答える
0

アプリケーションに渡された場合、自動的に生成された BSON ObjectID を一意の識別子として使用することは常に良い考えではないことを付け加えたいと思います: ユーザーによって操作される可能性があります。

ObjectID は順番に生成されるように見えるため、必要な認証メカニズムを実装しないと、悪意のあるユーザーが値を単純に増やして、アクセスしてはならないリソースにアクセスする可能性があります。

更新:バージョン 3.4+ 以降、ObjectID はインクリメンタルに生成されなくなりました。3.2 のドキュメント最新のドキュメントを参照してください。

したがって、UUID タイプの識別子を使用すると、あいまいさによるセキュリティのレイヤーが提供されます。もちろん、承認 (このユーザーが要求されたリソースへのアクセスを許可されているかどうか) は必須ですが、前述の ObjectID 機能に注意する必要があります。

両方の長所を活かすには、ObjectID の長さ (12 または 24 文字) に一致する UUID を生成し、それを使用して ObjectID タイプの独自の _id を作成します。

于 2016-10-31T13:10:21.883 に答える