2015-11-11 109 views
1

嵌套查詢我有三個模式:用戶,帖子和評論與貓鼬

var User = new Schema({ 
    name: String, 
    email: String, 
    password: String // obviously encrypted 
}); 

var Post = new Schema({ 
    title: String, 
    author: { type: Schema.ObjectId, ref: 'User' } 
}); 

var Comment = new Schema({ 
    text: String, 
    post: { type: Schema.ObjectId, ref: 'Post' }, 
    author: { type: Schema.ObjectId, ref: 'User' } 
}); 

我需要在對用戶有評論所有帖子。

我知道它應該是一個非常簡單和常見的用例,但現在我無法想象沒有多次調用並手動迭代結果的查詢方法。

我一直在想加入comments場到Post架構(我寧願避免),使類似的:

Post.find() 
    .populate({ path: 'comments', match: { author: user } }) 
    .exec(function (err, posts) { 
     console.log(posts); 
    }); 

任何線索,而無需修改我原來的模式?

謝謝

回答

0

你基本上有兩種方法來解決這個問題。

1)沒有填充。這使用承諾與多個電話。首先查詢特定用戶的Comment模型,然後在回調中使用註釋中的帖子ID來獲取帖子。您可以使用promises這樣的:

var promise = Comment.find({ "author": userId }).select("post").exec(); 
promise.then(function (comments) { 
    var postIds = comments.map(function (c) { 
     return c.post; 
    }); 
    return Post.find({ "_id": { "$in": postIds }).exec(); 
}).then(function (posts) { 
    // do something with the posts here 
    console.log(posts); 

}).then(null, function (err) { 
    // handle error here 
}); 

2)使用填充。使用給定的用戶id查詢特定用戶的Comment模型,選擇你想要的後場和填充它:

var query = Comment.find({ "author": userId }); 
query.select("post").populate("post"); 
query.exec(function(err, results){  
    console.log(results); 
    var posts = results.map(function (r) { return r.post; }); 
    console.log(posts); 
}); 
+0

看起來有前途的(沒有雙關語意),但它正是我指的是在我的崗位當我說我找到一種方法來避免多次調用(有兩個'find's)和迭代(map)。 – javorosas

+0

@javorosas使用另一種方法更新了我的答案,這種方法不需要多次調用,但是可以操縱結果數組以僅返回帖子,更接近您正在尋找的內容。 – chridam