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.