これに対する 1 つの解決策は、コメントを直接クエリできる別のモデルとして保存し、関連する ObjectId への参照とコメントと投稿の間のパスを保存することです。
Mongoose 関連ドキュメントでPopulate機能を使用すると、埋め込みドキュメントと同様に機能しますが、クエリを実行する方法にはいくつかの重要な違いがあり、リレーションシップが読み込まれた状態を維持するように注意する必要があります。
次のように設定します。
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, ObjectId = Schema.Types.ObjectId;
var PostsSchema = new Schema({
body : String,
stories : [{ type: ObjectId, ref: 'Story' }]
});
var CommentsSchema = new Schema({
body : String,
post : { type: ObjectId, ref: 'Post' },
comments : [{ type: ObjectId, ref: 'Comment' }]
});
var Story = mongoose.model('Post', PostsSchema);
var Comment = mongoose.model('Comment', CommentsSchema);
このようにすると、すべてのコメントを含む投稿を取得するために、より多くのクエリが必要になります (単一のクエリで投稿とその完全なコメント階層をロードできるよりも遅くなります) が、コメントを直接クエリすることができます。それらが作成された投稿を取得します(ただし、コメントがネストされている場合、コメントへの完全なパスを簡単に見つけることはできません)。
これらはすべてトレードオフです。最善の決定 (コメントを再帰的に検索するか、コメントを個別に保存してから再帰的にロードするか) は、アプリケーションとその予想される使用パターンのコンテキストで行う必要があります。
もう1つの注意事項。populate 機能は現在、リンクされた ObjectId の単一レベルに制限されています。完全なネストされたデータセットを取得するには、返されるコメントごとに呼び出す必要があります。mongoose-subpopulateなど、これを支援するいくつかのプラグインがあり、すぐに Mongoose でネイティブにサポートされる予定です。github の問題はこちらを参照してください。