MongoDB $ set不更新记录 [英] MongoDB $set not updating record

查看:96
本文介绍了MongoDB $ set不更新记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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
));

使用findOnevar_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆