web-dev-qa-db-ja.com

Mongooseでのスキーマの変更への対処

アプリケーションの進化に応じてMongooseスキーマを更新/移行するためのベストプラクティス(またはツール)は何ですか?

69
mahemoff

更新:テスト済み、これは現在の形式では機能せず、正しいアイデアが得られたので、モジュール自体。しかし、いくつかの大きな変更をせずにさまざまなスキーマを追跡することなく、意図したとおりに機能するとは思われません。


Mongoose-data-migrationsが必要なようです

使用するドキュメントの古いスキーマバージョンを移行することを目的としています。これは、mongodbでの移行を処理する最良の方法と思われます。

ドキュメントコレクション(ala alter table)で完全なデータセットの移行を実行することは望ましくありません。サーバーに大きな負荷がかかり、アプリケーション/サーバーのダウンタイムが必要になる可能性があるためです。時々、すべてのドキュメントを取得して新しいスキーマ/変更を適用し、saveを呼び出すスクリプトを書く必要があるかもしれませんが、いつ/どこでそれを行うかを理解する必要があります。たとえば、移行ロジックをdoc initに追加すると、移行スクリプトを実行するためにサーバーを3時間停止するよりもパフォーマンスに大きな影響があります。

私はこれを見つけました link 同様に非常に有用で、基本的に上記をより詳細に繰り返し、基本的に上記のノードパッケージの概念をPHPで実装します。

N.B。モジュールは5か月前、0フォークですが、辺りを見回しており、abdelsaidの応答スタイルよりも優れた/役立つものは見つかりません。

5
Louis

面白いことですが、MongoDBはRDBMSのスキーマの問題に対応するために生まれました。何も移行する必要はありません。フィールドが必要な場合は、スキーマ定義でデフォルト値を設定するだけです。

new Schema({
    name: { type: string }
})

に:

new Schema({
    name: { type: string },
    birthplace: { type: string, required: true, default: 'neverborn' }
});
36
vimdude

スキーマの変更を反映するためにデータベースを更新する必要があるところで、この問題が発生しました。いくつかの調査の後、mongoコンソールでupdateMany()関数を試して更新を行うことにしましたが、かなりうまくいったと思います。

これをvimdudeの例に適用するには、コードは次のようになります。

try { db.<collection>.updateMany( { birthplace: null }, { $set: {"birthplace": "neverborn" } } ); } catch(e) { print(e); }

UpdateMany()関数は、フィルターに基づいてコレクション内のすべてのドキュメントを更新します。この場合、フィルターは、フィールド「birthplace」がnullであるすべてのドキュメントを探します。次に、これらのドキュメントに「birthplace」という名前の新しいフィールドを設定し、その値を「neverborn」に設定します。

コードを実行した後、状況を反映するように変更を実行します。

db.<collection>.find().pretty()

変更が行われたことを確認します。 「neverborn」という値を持つ新しいフィールド「birthplace」は、コレクション内の各ドキュメントの最後に表示されます。

お役に立てば幸いです。

6