2

前に近道をして、さまざまなフィールドを連結して「一意の ID」を作成することで、Mongo データベースの主キーを作成しました。

ObjectId を実際に使用するように変更したいと思います。それを行うための最良のアプローチは何ですか?私は 300 万を少し超えるドキュメントを持っており、これができるだけ混乱を招かないようにしたいと考えています。

簡単な方法は、サイトを少しダウンさせてから、すべてのドキュメントを ObjectIds を使用しているドキュメントから別のドキュメントにコピーすることですが、できればアプリケーションを実行し続けたいと思います。移行が行われている間、両方に書き込む方法があると思いますが、それには2つの同様のコードベースが必要になるため、それをすべて回避する方法があるかどうか疑問に思います。

追加情報を提供するには、他のコレクションから参照されていない 1 つのコレクションにすぎません。この MongoDB コレクションから読み取るクエリを作成するために使用されるいくつかの値を含む別の MySQL データベースがあります。

PyMongo/Mongoengine ライブラリを使用して Python から MongoDB とやり取りしていますが、コレクションの主キーを変更するだけでよいかどうかわかりません。

4

1 に答える 1

3

サイト自体がダウンしない場合は、いかなる理由でもサイトをダウンさせるべきではありません。:)

何百万ものレコードがあっても、問題の解決策は ID の使い方にあります。

これらの ID を使用して異なるコレクション内のドキュメントを相互参照すると、更新されたオブジェクトごとに、このオブジェクトを参照する他のすべてのオブジェクトが更新されます。

最初のステップとして、システムを更新して、古い方法で新しいオブジェクトを作成しないようにする必要があります。システムでこれを簡単に実行できる場合は、データベースを非常に簡単に更新できます。この変更が簡単でない場合は、システムにアーキテクチャ上の問題があり、最初にこれを変更する必要があります。このような状況の場合は、回答を更新できるように質問を更新してください。

私はあなたのアプリケーションとデータについて何も知らないので、私が言うことはあまりにも一般的です. coll_bad_id を更新したいコレクションを呼び出しましょう。このコレクションのすべてのアイテムは、coll_poor_guy や coll_wisdom_searcher などの他のコレクションで参照されます。これを行う方法は、次のように coll_bad_id を一度に 1 つずつ実行することです。

1. read one item
2. update _id with new style of _id
3. insert item back to collection
    -- now we have two copies of the same item one with old-style id, one with new
4. update each item referencing this to use new style id
5. remove the duplicate item with old-style id from collection

覚えておくべきことの 1 つは、bson ObjectId が非常に役立つ日付/時刻データを保持していることです。これらすべてのオブジェクトを 1 日に再構築するため、ObjectId にはこれらのアイテムの正しい作成時間が反映されません。新しく追加されたアイテムについては、そうします。最初に新しく追加されたアイテムは、正しい作成時間の ID を持つアイテムのマイルストーンとして記録できます。

更新: Mongo シェルで実行するコード サンプル。これは最も効率的な方法ではありません。しかし、新しい _id で追加する前に何も削除しないので、安全に実行できます。find() 呼び出しにクエリを追加することで、これを少量で行うことができます。

var cursor = db.testcoll.find()

cursor.forEach(function(item) {
    var oldid= item._id; // we save old _id to use for removal below.
    delete item._id; // When we add an item without _id, Mongo creates a unique _id.
    db.testcoll.insert(item); // We add item without _id.
    db.testcoll.remove(oldid); // We delete the item with bad _id.
});
于 2012-07-08T16:39:58.727 に答える