Javascript Can';t合并查询结果以创建显示最新消息的即时消息收件箱
我正在开发一个基于线程/对话的即时消息功能(很像Facebook、社交网站等)。我试图让我的API为经过身份验证的用户所参与的会话列表提供服务,以及每个会话中的最新消息 这件事我已经坚持了好几天了,我尝试了很多东西。我在这方面运气不好。若我将我的消息作为对话的子文档,我可以做到这一点,但我所读到的内容表明,要避免像这样嵌套无限数组。我很好奇我是否应该考虑一个模式的重新设计,但首先我想看看是否有一个查询可以让我找到我需要的地方。 这是我的架构设置: Conversation.js:Javascript Can';t合并查询结果以创建显示最新消息的即时消息收件箱,javascript,node.js,mongodb,express,mongoose,Javascript,Node.js,Mongodb,Express,Mongoose,我正在开发一个基于线程/对话的即时消息功能(很像Facebook、社交网站等)。我试图让我的API为经过身份验证的用户所参与的会话列表提供服务,以及每个会话中的最新消息 这件事我已经坚持了好几天了,我尝试了很多东西。我在这方面运气不好。若我将我的消息作为对话的子文档,我可以做到这一点,但我所读到的内容表明,要避免像这样嵌套无限数组。我很好奇我是否应该考虑一个模式的重新设计,但首先我想看看是否有一个查询可以让我找到我需要的地方。 这是我的架构设置: Conversation.js: const m
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);
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);
Message.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);
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 });
});
}
正确的信息记录在控制台中。我曾尝试推送并连接到fullConversations数组,但结果在响应中为空。我也不确定是否要为与该forEach的每个单独对话运行单独的查询。这对我来说似乎效率不高,但我正在努力寻找另一种可行的方法。任何帮助或建议都将不胜感激。谢谢大家! 根据Mozilla文档,
concat
实际上返回一个新数组,而不更新当前数组()
尝试改用push
,因为它将更改当前数组()
编辑:NVM,你说你试过推。我认为这可能与异步的东西有关。我很快会发布一个更好的答案。我猜您是在异步运行更新fullConversations数组的函数,因此在函数实际添加任何数据之前返回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 });
关于这个问题你是对的!下面是修复它的代码:感谢您的帮助。