2011-06-01 8 views
0

私はMongooseを初めて利用しています。検索に問題があります。埋め込み文書を検索するMongoose + nodejs

これらは私のスキーマです:

var CommentSchema = new Schema({ 
    body  : String 
    , comments : [CommentSchema] 
}); 

var PostSchema = new Schema({ 
    body  : String 
    , comments : [CommentSchema] 
}); 

コメントのネストが深いです。誰かが既存のコメントに答えると、どうすればそのコメントを見つけることができますか?

答えて

0

githubのmongooseテストスイートを例に見ることができます。ここで

model_querying_test

あなたが探しているものです:埋め込まれた文書のフィールドに基づいて

テスト見つける:これまで

function() { 
    var db = start(), BlogPostB = db.model('BlogPostB', collection); 

    BlogPostB.create({comments: [{title: 'i should be queryable'}]}, function (err, created) { 
     should.strictEqual(err, null); 
     BlogPostB.findOne({'comments.title': 'i should be queryable'}, function (err, found) { 
     should.strictEqual(err, null); 
     found._id.should.eql(created._id); 
     db.close(); 
     }); 
    }); 
    }, 
+0

ただし、この検索は1つのネストレベルにのみ適用されます。私は深い入れ子の構造を持っていると私は 'ブログ { コメント { コメント { コメント {このコメント} }}}' と私はドンコメントを見つけたいと思うたびに」検索したい場合はどういくつのネスティングレベルがあるか知っています。 – kulebyashik

+0

しかし、彼らは同じ構造 'Comments.add({ コメント:[コメント] を})が...待っ;' はそれを見つけることができません、私は – kulebyashik

+0

ハズレを試してみましょう。私はそれを手動で検索する必要があると思う。ポイントは、私は "正しい方法"を知らないということです。手動検索の場合、 'for(i = 0 ...){if(hasComments)recursive()}'のようなsmthは「正しい」方法なので、私はそれを行います。簡単な方法があるかどうかわかりません。 p.s.とにかくFindOneメソッドは、コメントではなく投稿を探します。 – kulebyashik

0

一つの解決策は、これを使用し、別のモデルとしてコメントを格納することです直接問い合わせを行い、関連する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 issue hereを参照してください。

関連する問題