我有一个基于mongo的应用程序,可以显示报告。 在每个报告中,用户可以发布向所有其他用户显示的评论,以及回复现有评论。有两个"级别"评论,最高评论没有"父母",并回复"父母"。评论存储在数组"讨论"中,每个都有另一个名为"回复"的数组。
db.reports.findOne()
{
"_id" : "L154654258",
"timestamp" : ISODate("2016-03-17T01:15:00Z"),
"title" : "Server Offline",
"content" : "A server has become offline due to reason X112",
"discussions" : [
{
"id" : ObjectId("57beb8068d9da75ed44e0ebc"),
"user_id" : "david",
"timestamp" : ISODate("2016-03-17T01:15:00Z"),
"comment" : "Is this the first time that it happens?",
"last_edit" : null,
"replies" : [
{
"id" : ObjectId("57beb8068d9da75ed44e0ebd"),
"user_id" : "gene",
"timestamp" : ISODate("2016-03-17T01:20:00Z"),
"comment" : "I have never seen anything like that before",
"last_edit" : null
},
{
"id" : ObjectId("57c480b7ee568ddc634fd977"),
"user_id" : "david",
"timestamp" : ISODate("2016-03-20T01:20:00Z"),
"comment" : "Thanks!",
"last_edit" : null
}
}
]
}
到目前为止,使用此方案,我能够处理为每个评论插入新项目(父母和回复),以及编辑父母的内容(如果用户选择编辑他们的帖子),使用位置$运算符。 我的问题是更新回复。我试过这个(我以为它不会工作,只是想测试一下):
db.reports.findOne({'_id': 'L154654258', 'discussions': {'$elemMatch': {'id': ObjectId("57beb8068d9da75ed44e0ebc"), 'replies': {'$elemMatch': {'id': ObjectId("57beb8068d9da75ed44e0ebd")}}}}},
{'$set' : {'discussions.$.replies.$.comment': "This is a test!", 'discussions.$.replies.$.last_edit': 'Fantastic'}}
)
使用findOne()测试此查询似乎表明查询的查找部分有效。但是,如何更新数组的数组元素? 我假设使用$运算符两次没有工作,但有没有办法做到这一点,还是我需要使用Javascript? 谢谢!
答案 0 :(得分:1)
您无法使用$运算符执行此操作。它将始终更新第一个元素。您必须找到该文档,在服务器中进行更改,然后将其保存回mongo。
答案 1 :(得分:1)
尝试以下内容: -
var findQuery = {'_id': 'L154654258', 'discussions.replies.id': ObjectId("57beb8068d9da75ed44e0ebd")};
db.restaurants.find(
findQuery).toArray(
function(err, result)
{
if(err)
{
console.log(err);
}
else if(result && result.length)
{
var index,found = false;
for(var j in result[0].discussions){
for(var i in result[0].discussions[j].replies)
{
if(results[0].discussions[j].replies[i].id == ObjectId("57beb8068d9da75ed44e0ebd"))
{
found = true;
index = i;
break;
}
}
}
if(found)
{
var x = 'discussions.$.replies.'+index+'.last_edit';
var updateObject = {$set : {}};
updateObject['$set'][x] = 'Fantastic';
db.restaurants.update(findQuery, updateObject);
}
});
}
答案 2 :(得分:0)
根据Sharabanee的代码,以下代码对我有用:
var findQuery = {'_id': 'L154654258', 'discussions.replies.id': ObjectId("57beb8068d9da75ed44e0ebd")};
var result = db.reports.find(findQuery).toArray();
var index,found = false;
for(var j in result[0].discussions) {
for(var i in result[0].discussions[j].replies) {
if(result[0].discussions[j].replies[i].id.equals(ObjectId("57beb8068d9da75ed44e0ebd"))) {
found = true;
index = i;
break;
}
}
}
if(found) {
var x = 'discussions.$.replies.'+index+'.comment';
var updateObject = {$set : {}};
updateObject['$set'][x] = 'Fantastic';
db.reports.update(findQuery, updateObject);
}
答案 3 :(得分:0)