MongoDB $ set不更新记录 [英] MongoDB $set not updating record
问题描述
我正在使用PHP PECL扩展名对MongoDB进行试验,但是我很难使某个更新查询起作用.我已经四处寻找运气不好的答案.
I'm experimenting with MongoDB using the PHP PECL extension, however I'm having difficulty getting a certain update query to work. I have searched around on SO for answers with little luck.
我已经创建了一个基本集合:
I have created a basic collection:
$m = new Mongo;
$collection = $m->testdb->testcollection;
$collection->insert(array(
0, 1, 1, 2, 3, 5
));
使用findOne
和var_dump
记录显示如下:
array
'_id' =>
object(MongoId)[6]
public '$id' => string '4f3bde65a1f7a0315b000000' (length=24)
0 => int 0
1 => int 1
2 => int 1
3 => int 2
4 => int 3
5 => int 5
当我想使用$set
更新时出现问题.我将查询基于显示在 SQL到Mongo备忘单底部的映射上在PHP手册中
The problem comes when I want to update using $set
. I am basing my query on the mapping shown towards the bottom of the SQL to Mongo Cheat Sheet in the PHP manual
在这里我想将字段0
更新为值100
Here I want to update field 0
to value 100
$obj = $collection->findOne();
$collection->update(
array('_id' => $obj['_id']),
array('$set' => array(0 => 100))
);
重新获取记录表明该记录保持不变.
Re-fetching the record shows that it remains unchanged.
我确实想知道我是否对_id
做错了,但是以下更新查询可以起作用,尽管用新值替换了整个记录,而不是简单地更新了一个字段.
I did wonder if I was doing something wrong with the _id
, however the following update query does work, albeit replacing the entire record with a new value, not simply updating the one field.
$collection->update(
array('_id' => $obj['_id']),
array(0 => 100)
);
对象转储:
array
'_id' =>
object(MongoId)[7]
public '$id' => string '4f3bde65a1f7a0315b000000' (length=24)
0 => int 100
有人可以指出我做错了什么,以及如何正确使用$set
.我敢肯定,这很明显,我只需要再看一眼即可.
Can someone please point out what I am doing wrong, and how to properly use $set
. I'm sure it's obvious and I just need a second pair of eyes on it.
非常感谢.
推荐答案
我正在做一些调查为什么会发生这种情况.而且我认为我找不到解决该问题的方法.
I've doing some investigations to why this happens. And I don't think I can find a way on how to "fix" this issue.
JavaScript在数组和关联数组/对象之间有区别. PHP在数组和对象之间有区别.对于PHP,关联数组是一个数组,对于JavaScript,它是一个对象.
JavaScript has a difference between arrays and associative arrays/objects. PHP has the difference between arrays and objects. For PHP an associative array is an array, and for JavaScript it is an object.
当PHP驱动程序需要将数组转换为JSON对象时,它将尝试找出数组是否为:具有从0开始按顺序编号的键的普通数组;或者从0开始的常规数组.或关联数组.当前实现将任何具有顺序编号的键的数组作为对象,从0开始为普通数组.而且普通数组不包含 keys .这就是问题所在.在这种情况下,驱动程序会看到一个正常的数组,在BSON中没有发送到服务器的字段名称信息,因此服务器无法更新字段.
When the PHP driver needs to convert an array to a JSON object, it tries to figure out whether an array is either: a normal array with sequentially numbered keys starting with 0; or an associative array. The current implementation regards any array with sequentially numbered keys, starting from 0 an normal array. And a normal array does not contain keys. And this is the problem. In the situation the driver sees a normal array, there is no field name information in the BSON that's send to the server, and hence the server can't update a field.
在不破坏任何现有代码的情况下,我想不出一种改变这种行为的方法.因此,如果要使用数字字段名,则必须对主文档"使用stdClass对象.或者,您可以将这些键推入嵌入式文档中,然后进行更新:
I can't think of a way to change this behaviour without breaking any sort of existing code. So if you want numerical fieldnames, you will have to use a stdClass object for the "main document". Alternatively, you could push those keys into a embedded document and then update:
<?php
$m = new Mongo;
$collection = $m->demo->testcollection;
$collection->insert(array(
"_id" => 'bug341',
'data' => array( 0, 1, 1, 2, 3, 5 )
));
$obj = $collection->findOne();
$update = array('data.0' => 'zero int');
$collection->update(
array( '_id' => 'bug341' ),
array( '$set' => $update )
);
$obj = $collection->findOne();
var_dump($obj);
?>
这篇关于MongoDB $ set不更新记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!