わかりました。自分よりも良い答えを待つ間、これまでやってきたことを投稿しようと思います。
プリ/ポストミドルウェア
私が最初に試したのは、プレ/ポストミドルウェア
を使用することでした。 相互に参照するドキュメントを同期します。 (たとえば、Author
がある場合 およびQuote
、および作成者には、次のタイプの配列があります:quotes: [{type: Schema.Types.ObjectId, ref:'Quotes'}]
、その後、見積もりが削除されるたびに、その_id
を削除する必要があります アレイから。または、作成者が削除された場合は、すべての引用を削除することをお勧めします。
このアプローチには重要な利点があります :各スキーマを独自のファイルで定義すると、そこでミドルウェアを定義して、すべてをきちんと整理することができます。 。スキーマを見ると、そのすぐ下で、スキーマの機能、変更が他のエンティティにどのように影響するかなどを確認できます。
var Quote = new Schema({
//fields in schema
})
//its quite clear what happens when you remove an entity
Quote.pre('remove', function(next) {
Author.update(
//remove quote from Author quotes array.
)
})
主な欠点 ただし、これらのフックは、updateまたはModel静的更新/削除関数を呼び出したときに実行されないということです
。むしろ、ドキュメントを取得してからsave()
を呼び出す必要があります またはremove()
それらに。
もう1つの小さな欠点は、Quoteが更新または削除されるたびに更新できるように、Quoteがそれを参照する人を認識する必要があることです。したがって、Period
としましょう。 引用符のリストとAuthor
があります 見積もりのリストもあります。見積もりを更新するには、これら2つについて知る必要があります。
これは、これらの関数がアトミッククエリをデータベースに直接送信するためです。これは素晴らしいことですが、save()
を使用することの間の矛盾は嫌いです およびModel.Update(...)
。おそらく、他の誰かまたはあなたが将来、誤って静的更新機能を使用し、ミドルウェアがトリガーされないため、取り除くのに苦労する頭痛の種になります。
NodeJSイベントメカニズム
私が現在行っていることは実際には最適ではありませんが、実際に短所を上回るのに十分な利点があります(または、誰かが私に素晴らしいフィードバックを提供してくれると信じています)。モデルをラップするサービス、たとえばAuthorService
を作成しました events.EventEmitter
を拡張します コンストラクター関数であり、おおよそ次のようになります。
function AuthorService() {
var self = this
this.create = function() {...}
this.update = function() {
...
self.emit('AuthorUpdated, before, after)
...
}
}
util.inherits(AuthorService, events.EventEmitter)
module.exports = new AuthorService()
利点:
- 関心のある機能はすべてServiceeventsに登録して、通知を受けることができます。そうすれば、たとえば、
Quote
isupdatedの場合、AuthorServiceはそれをリッスンし、Author
を更新できます。 によると。 (注1) - Quoteは、それを参照するすべてのドキュメントを認識する必要はありません。サービスは、
QuoteUpdated
をトリガーするだけです。 イベントと、これが発生したときに操作を実行する必要があるすべてのドキュメントがそうします。
注1:誰かがマングースと対話する必要があるときはいつでもこのサービスが使用される限り。
短所:
- マングースの代わりにサービスを直接使用して、定型コードを追加しました。
- イベントをトリガーしたときにどの関数が呼び出されるかは明確ではありません。
- 読みやすさを犠牲にしてプロデューサーとコンシューマーを分離します(
emit('EventName', args)
、どのサービスがこのイベントをリッスンしているかはすぐにはわかりません)
もう1つの欠点は、誰かがサービスからモデルを取得してsave()
を呼び出すことができることです。 、イベントはトリガーされません ただし、これは、これら2つのソリューション間の何らかのハイブリッドで対処できると確信しています。
私はこの分野での提案を非常に受け入れています(そのため、最初にこの質問を投稿しました)。