我有以下两种模式:
var UserSchema = new mongoose.Schema({
name: { type: String }
posts: {
owner: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }],
contributor: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }]
}
});
var PostSchema = new mongoose.Schema({
headline: { type: String, required: true }
authors: {
owner: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
contributors: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}
});
在我的应用程序的某些时候,我需要获取有关特定用户的帖子的信息。换句话说,我需要获取用户所有者或贡献者的帖子的id
和headline
。但是,对于用户是其贡献者的帖子,我还需要获取其作者的信息(获取id
)。
我试着开始做这样的事情:
User.findById(req.params.user_id)
.populate({ path: 'posts.owner', select: '_id headline' })
.populate({ path: 'posts.contributor', select: '_id headline'})
.exec(function(err, user) {
console.log(user);
});
但是我不确定如何从这里继续,或者即使这是正确的做法?你能伸出援助之手吗?
答案 0 :(得分:0)
如果您的帖子的标题不经常更改,您可以与用户文档一起存储,如下所示:
const UserSchema = new mongoose.Schema({
posts: {
owner: [{
headline: String,
post: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' }
}],
contributor: [{
headline: String,
post: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' }
}]
}
});
它会创建一些冗余,但是,它会让你不要只是为了获得帖子的标题而做出这么多的查询。
此外,为了保持一致性,您可以将预设中间件连接到Post模式,以便更新用户文档中的标题。你可以这样做:
PostSchema.pre('save', true, function(next, done) {
next();
if (!this.isModified('headline')) {
return done();
}
const User = mongoose.model('User');
return Promise.all([
User.update({'posts.owner': this._id}, {$set: {'posts.owner.$.headline': this.headline}}, {multi: true}).exec();
User.update({'posts.contributors': this._id}, {$set: {'posts.contributors.$.headline': this.headline}}, {multi: true}).exec();
])
.then(done)
.catch(done);
});
答案 1 :(得分:0)
我设法使用async
库以稍微不同的方式获取我需要的信息。
以下是代码:
User.findById(req.params.user_id, function(err, user) {
if(err) { throw err; }
// if no user is found
if(!user) {
return res.status(404).send({ message: { user: 'There is no such user.'} });
// something bad happened! The requested user does not exist.
}
async.parallel({
owner: function(callback) {
async.map(user.posts.owner, function(post, callback) {
Post.findById(post, 'headline').exec(callback);
}, callback);
},
contributor: function(callback) {
async.map(user.posts.owner, function(post, callback) {
Post.findById(post, 'headline authors.owner')
.populate({ path: 'authors.owner', select: 'name' })
.exec(callback);
}, callback);
}
}, function(err, results) {
if(err) { throw err; }
return res.json(results);
});
});