mongoose切片arrays,在填充字段
我有以下mongoose
模式:
主要的一个是userSchema
,其中包含好友friendSchema
。 每个friendSchema
是一个包含messageSchema
数组的对象。 messageSchema
是最深的对象,包含消息的主体。
var messageSchema = new mongoose.Schema({ ... body: String }); var conversationsSchema = new mongoose.Schema({ ... messages: [messageSchema] }); var friendSchema = new mongoose.Schema({ user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', }, conversation: { type: mongoose.Schema.Types.ObjectId, ref: 'Conversation', }, }, { _id : false }); var userSchema = new mongoose.Schema({ ... friends: [friendSchema] });
当检索特定用户的朋友时,我填充它的朋友configuration文件,如果存在对话,我也填充对话。 我该如何切片conversations.messages
数组,居住在conversation
对象的人口? 我不想回复整个消息。
var userId = req.userid; var populateQuery = [{ path:'friends.user', select: queries.overviewConversationFields }, { path:'friends.conversation' }]; User .find({ _id: userId }, { friends: 1 }) .populate(populateQuery) .exec(function(err, result){ if (err) { next(err); } console.log(result); }
编辑(1) :我试了
.slice('friends.conversation.messages', -3)
编辑(2) :我尝试填充查询
{ path:'friends.conversation', options: { 'friends.conversation.messages': { $slice: -2 } }
编辑(3) :现在,我可以实现我想要的,在查询执行后切片数组。 这根本没有被优化。
一个有效的解决方法。 我没有find如何$slice
驻留在填充字段中的数组。
但是 , $slice
操作符可以在任何array
上完美地工作,只要它的父文档没有被填充。
1)我决定更新conversationSchema
是添加一个包含参与对话的用户ID的数组:
var conversationsSchema = new mongoose.Schema({ users: [type: mongoose.Schema.Types.ObjectId], messages: [messageSchema] });
2)然后,我可以很容易地find我的用户参与的每个对话。 正如我所说,我可以正确地切片messages
数组,因为什么都不必填充。
Conversation.find({ users: userId }, { 'messages': { $slice: -1 }}, function(err, conversation) { });
3)最后,我要做的就是分别查询所有朋友和对话,然后把所有东西放在一起,用一个简单的循环和一个_find
。 这样做或多或less是一个蒙古人的相同程序
使用async.parallel
提高效率:
async.parallel({ friends: function(done){ User .find({ _id: userId }, { friends: 1 }) .populate(populateQuery) .exec(function(err, result){ if (err) { return done(err);} done(null, result[0].friends); }); }, conversations: function(done){ Conversation.find({ users: userId }, { 'messages': { $slice: -1 }}, function(err, conversation) { if (err) { return done(err); } done(null, conversation) }); }}, function(err, results) { if (err) { return next(err); } var friends = results.friends; var conversations = results.conversations; for (var i = 0; i < friends.length; i++) { if (friends[i].conversation) { friends[i].conversation = _.find(conversations, function(conv){ return conv._id.equals(new ObjectId(friends[i].conversation)); }); } } }); // Friends contains now every conversation, with the last sent message.