2016-03-06 44 views
0

我正在聊天室中,用户可以在项目基础上过滤彼此聊天。来自同一个项目的用户可以相互交谈。在节点/快递中推送到mongodb的二级数组

这里是我的聊天模式,每个文件是基于项目编号,并具有与用户REFFERENCE消息数组:

'use strict'; 
var mongoose = require('bluebird').promisifyAll(require('mongoose')); 
var ChatSchema = new mongoose.Schema({ 
    projectid: { 
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'Project' 
    }, 
    messages: [{ 
    userid: { 
     type: mongoose.Schema.Types.ObjectId, 
     ref: 'User' 
    }, 
    message: String, 
    date: { 
     type: Date, 
     default: Date.now 
    }, 
    time: String 
    }] 
}); 
export default mongoose.model('Chat', ChatSchema); 

现在我尝试更新的消息数组新邮件,但我过去几个小时无法这样做。这是我到目前为止。

要获取聊天基于项目的消息,我使用:

路线:

router.get('/projectid/:id', controller.showByProject); 
router.post('/projectid/:id', controller.insertMessageByProject); 

控制器:

// Gets the chat thread based on project id 
export function showByProject(req, res) { 
    Chat.findAsync({projectid: req.params.id}) 
    .then(handleEntityNotFound(res)) 
    .then(respondWithResult(res)) 
    .catch(handleError(res)); 
} 

// Insert a new message in the chat based on projectid 
export function insertMessageByProject(req, res) { 
    if (req.body._id) { 
    delete req.body._id; 
    } 
    Chat.findAsync({projectid: req.params.id}) 
    .then(handleEntityNotFound(res)) 
    .then(saveUpdates({$push: {messages: req.body}})) 
    .then(respondWithResult(res)) 
    .catch(handleError(res)); 
} 

JSON对象我从邮差送:

{ 
    "messages": 
    { 
     "userid": "56d7967745ab81322a964927", 
     "message": "This is a meesage" 
    } 
} 

OR

{ 
    "userid": "56d7967745ab81322a964927", 
    "message": "This is a meesage" 
} 

我可以,如果我有对象ID聊天文件本身,而是我的应用程序内更新对象,我没有直接引用。我也试过其他几种方法,但每次我的应用程序返回500错误。

您的帮助将不胜感激。

编辑1:这里是我正在使用的角度全堆栈插件生成的帮助功能。

function respondWithResult(res, statusCode) { 
    statusCode = statusCode || 200; 
    return function(entity) { 
    if (entity) { 
     res.status(statusCode).json(entity); 
    } 
    }; 
} 

function saveUpdates(updates) { 
    return function(entity) { 
    var updated = _.merge(entity, updates); 
    return updated.saveAsync() 
     .spread(updated => { 
     return updated; 
     }); 
    }; 
} 

function removeEntity(res) { 
    return function(entity) { 
    if (entity) { 
     return entity.removeAsync() 
     .then(() => { 
      res.status(204).end(); 
     }); 
    } 
    }; 
} 

function handleEntityNotFound(res) { 
    return function(entity) { 
    if (!entity) { 
     res.status(404).end(); 
     return null; 
    } 
    return entity; 
    }; 
} 

function handleError(res, statusCode) { 
    statusCode = statusCode || 500; 
    return function(err) { 
    res.status(statusCode).send(err); 
    }; 
} 

编辑2:正如我在评论中提到的,问题是与_.Merge功能,没有合并对象的权利,但它应该是能够更新的对象。

所以我写了我自己的功能saveUpdates如下:

function saveUpdatesForNewChat(updates) { 
    return function(entity) { 

    var temp = entity; 
    temp[0].messages.push(updates); 

    console.log('\ntemp:'); 
    console.log(require('util').inspect(temp, { depth: null })); 
    console.log('\nend of ops\n\n'); 

    var updated = _.merge(entity, temp); 
    console.log('out of merge'); 
    console.log(require('util').inspect(updated, { depth: null })); 
    return updated.saveAsync() 
     .spread(updated => { 
     return updated; 
     }); 
    }; 
} 

行,所以我已经离开了控制台日志里面,它是完美的对象保存到数据库中,但服务器仍然返回500错误上更新。

+0

有东西在里面发臭。你传递给'then'和'catch'的函数在你传递它们时被调用。你应该传递一个函数的定义(只是handleEntityNotFound或handleError或东西,没有参数,没有括号)。 – lascort

+0

我想我明白你在说什么。这是我第一次使用mean-stack,但他们正在为我的项目使用不同的其他对象。 此外'showByProject'函数按预期工作。 –

+0

更新:尝试'toJson'或'toObject',它们不起作用。还尝试操纵这里提供的代码:http://mongoosejs.com/docs/documents.html。我现在确定问题出在'_.merge'的'saveUpdates'函数中。我创建了一个新函数并尝试使用聊天'_id'进行更新,最大它将第二级文档中的所有消息替换为第一条消息。 6个小时,我仍然不知道我在做什么。 –

回答

0

好的!所以我自己找到了答案。

问题是返回的对象是结果集,我在整个结果集上调用save。我从返回的结果集中提取第一个元素,将新消息推送到元素并调用save并开始工作。

下面是代码:

function saveUpdatesForNewChat(updates) { 
    return function(entity) { 
    var temp = entity[0]; 
    temp.messages.push(updates); 
    var updated = temp; 
    return updated.saveAsync() 
     .spread(updated => { 
     return updated; 
     }); 
    }; 
}