Mongodb 2.6.0-rc2和PHP 1.4.5 - 找到_id $ in

Pav*_*vel 8 php mongodb mongodb-php

像这样的简单查询:

$a = array('_id' => array( '$in' => array_values($ids) ) ); 
var_dump($a);
$cursor2 = $data->find( $a );
Run Code Online (Sandbox Code Playgroud)

在mongodb 2.4.9中工作,但是,在2.6.0-rc2中返回:

Type: MongoCursorException
Code: 17287
Message: Can't canonicalize query: BadValue $in needs an array
Run Code Online (Sandbox Code Playgroud)

var_dump的输出:

array(1) {
  ["_id"]=>
  array(1) {
    ["$in"]=>
    array(10) {
      [0]=>
      object(MongoId)#57 (1) {
        ["$id"]=>
        string(24) "52214d60012f8aab278eacb6"
      }
      [1]=>
      object(MongoId)#58 (1) {
        ["$id"]=>
        string(24) "52214d60012f8aab278eaca8"
      }
      [2]=>
      object(MongoId)#59 (1) {
        ["$id"]=>
        string(24) "52214d60012f8aab278eaca7"
      }
   }
}
}
Run Code Online (Sandbox Code Playgroud)

我想知道这是Mongo还是PHP相关?

谢谢!

bjo*_*ori 10

这...是MongoDB 2.6.0中的一个更改,不再接受bson$in子句中的对象.

这个特殊问题在https://jira.mongodb.org/browse/PHP-1051上作为PHP驱动程序错误被跟踪.

当PHP数组为:时,MongoDB PHP驱动程序将PHP数组序列化为BSON数组(由$ in运算符接受):顺序数字索引,从0开始

这意味着如果你有一个像这样的数组:

$array = array($id0, $id1, $id2, $id3, $id4);
Run Code Online (Sandbox Code Playgroud)

然后你

unset($array[0]);
Run Code Online (Sandbox Code Playgroud)

你实际上结束了:

$array = array(1 => $id1, 2 => $id2, 3 => $id3, 4 => $id);
Run Code Online (Sandbox Code Playgroud)

这不是从索引0开始的.因此MongoDB PHP驱动程序将其转换为BSON对象...导致MongoDB中的验证错误,因为它需要一个数组.

现在,由于MongoDB PHP驱动程序没有解析您的MongoDB查询,我们无法知道哪个数组应该免于此序列化规则.

如上所述,解决方法是确保从0开始对PHP数组进行数字索引.最简单的方法是运行

array_values($values);
Run Code Online (Sandbox Code Playgroud)


Pav*_*vel 2

用 mongo 调试后,我注意到以下内容:

...查询:{ _id:{ $in:{ 0:ObjectId('52214d60012f8aab278eaad1') ...

但应该是

...查询:{ _id:{ $in:[ ObjectId('52214d60012f8aab278eaad1') ...

所以,我建议在调用 $in 之前执行 array_values($VAR) ,我猜 Mongo 2.4.9 对 $ids 可以是对象或数组这一事实更加宽容,请确保在 mongo 2.6 中使用数组; )