无法合并查询结果以创build显示最新消息的即时消息收件箱

我正在研究基于线程/对话的即时消息function(很像Facebook,环聊等)。 我试图让我的API提供经过身份validation的用户参与的对话列表,以及每个对话中最新的消息。

我已经坚持了几天,我已经尝试了很多东西。 我没有聚集运气。 如果我把我的信息作为对话的一个子文档,我可以做到这一点,但是我所读到的是避免嵌套像这样的无限数组。 我很好奇,如果我应该考虑一个模式重新devise,但首先我想看看是否有一个查询,可以让我在我需要的地方。

这是我的架构设置:

Conversation.js:

const mongoose = require('mongoose'), Schema = mongoose.Schema; // Schema defines how chat messages will be stored in MongoDB const ConversationSchema = new Schema({ participants: [{ type: Schema.Types.ObjectId, ref: 'User'}], }); module.exports = mongoose.model('Conversation', ConversationSchema); 

Message.js:

 const mongoose = require('mongoose'), Schema = mongoose.Schema; const MessageSchema = new Schema({ conversationId: { type: Schema.Types.ObjectId, required: true }, body: { type: String, required: true }, author: { type: Schema.Types.ObjectId, ref: 'User' } }, { timestamps: true // Saves createdAt and updatedAt as dates. createdAt will be our timestamp. }); module.exports = mongoose.model('Message', MessageSchema); 

以下是到目前为止我所能达到的最接近我的结果的查询:

 // Only return one message from each conversation to display as snippet Conversation.find({ participants: req.user._id }) .select('_id') .exec(function(err, conversations) { if (err) { res.send({ error: err }); return next(err); } let fullConversations = []; conversations.forEach(function(conversation) { Message.find({ 'conversationId': conversation._id }) .sort('-createdAt') .limit(1) .exec(function(err, message) { fullConversations.concat(message); console.log(message); }); }); res.status(200).json({ conversations: fullConversations }); }); } 

正确的信息正在login控制台。 我已经尝试推送并连接到fullConversations数组,但它最终在响应中是空的。 我也不确定是否为每个单独的对话使用forEach来运行单独的查询。 对我来说这似乎并不高效,但我正在努力寻找另一种有效的方法。 任何帮助或build议将不胜感激。 谢谢!

我将猜测你正在更新的fullConversations数组正在asynchronous运行的函数,所以你返回fullConversations数组之前,函数实际上添加任何数据。

 let fullConversations = []; var notCompleted = conversations.length; conversations.forEach(function(conversation) { Message.find({ 'conversationId': conversation._id }) .sort('-createdAt') .limit(1) .exec(function(err, message) { fullConversations.push(message); notCompleted--; console.log(message); }); }); while (notCompleted > 0) { // Wait } res.status(200).json({ conversations: fullConversations }); 

根据Mozilla文档, concat实际上返回一个新的数组而不更新当前的( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

 var new_array = old_array.concat(value1[, value2[, ...[, valueN]]]) 

尝试使用push而不是因为它会改变当前的数组( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

 fullConversations.push(message); 

编辑:NVM,你说你试过推。 我认为这可能与asynchronous的东西有关。 我会很快发布一个更好的答案。