我有以下mongodb对象:
{
"_id": ObjectId("4d0b9c7a8b012fe287547157"),
"messages": {
"0": {
"toUname": "Eamorr3",
"fromUname": "Eamorr2",
"time": 1292606586,
"id": "ABCDZZZ",
"subject": "asdf",
"message": "asdf",
"read": 0 //I want to change this to 1!
},
"1": {
"toUname": "Eamorr1",
"fromUname": "Eamorr3",
"time": 1292606586,
"id": "EFGHZZZ",
"subject": "asdf2",
"message": "asdf2",
"read": 0
}
},
"uname": "Eamorr3"
}
如何将“read”设置为1,其中id = ABCDZZZZ?我正在使用PHP。
我尝试过以下命令:
$driverInboxes->update(array('uname'=>$uname),array('$set'=>array('messages'=>array('id'=>$id,'read'=>'1'))));
但是当我这样做时,覆盖发生了,我得到了:
{
"_id": ObjectId("4d0b9c7a8b012fe287547157"),
"messages": {
"id": "j7zwr2hzx14d3sucmvp5",
"read": "1"
},
"uname": "Eamorr3"
}
我完全陷入困境。任何帮助非常感谢。
我是否需要拉出整个数组元素,修改并再次将其推回?
非常感谢,
答案 0 :(得分:17)
如果你读了你的命令,你实际上在说:“UPDATE WHERE uname = Eamorr3 SET消息等于这个数组(id = blah,read = 1)”
当您在$set
上执行messages
时,您基本上是在指示它将您的数组作为新值。
但是,看起来您正在尝试将特定邮件更新为只读更复杂一点。所以这里有两个障碍:
1:您实际上正在更新messages.0.read
如果您执行array('$set' => array( 'messages.0.read' => 1 ) )
,则会更新正确的元素。关注该链,messages
是一个javascript对象,您想要更新属性0
。属性0
本身就是一个javascript对象,其中包含您要更新的属性read
。
你能看到你如何更新messages.0.read
吗?
这将我们带到问题#2。
2:0
是您的问题
如果你看看你在Mongo中构建数据的方式,那么消息对象实际上是低于标准的。 “0”和“1”目前充当“ids”并且它们不是非常有用。就个人而言,我会使用实际ID来构造您的对象,而不是“0”或“1”。
所以你的对象如下所示:
{
"_id": ObjectId("4d0b9c7a8b012fe287547157"),
"messages": {
"ABCDZZZ": {
"toUname": "Eamorr3",
"fromUname": "Eamorr2",
"time": 1292606586,
"subject": "asdf",
"message": "asdf",
"read": 0 //I want to change this to 1!
}
},
"uname": "Eamorr3"
}
现在你的更新命令变为:
array('$set' => array( 'messages.ABCDZZZ.read' => 1 ) )
此结构使更新特定邮件或邮件的特定部分变得更加容易。
答案 1 :(得分:2)
如果您想为各种目的保留阵列结构,可以使用Positional operator。这使您可以利用数组功能($ pop,$ push等),同时能够更新未知数组位置的元素。