2

我正在尝试使用如何安全更新 mongodb 中的序列号中描述的查询的 PHP 版本更新多个数组元素

其中描述了查询:

db.so.update(
{ _id: new ObjectId("4f55e7ba362e2f2a734c92f8")},
{ $set : { 'subs.1.order' : 3, 'subs.2.order' : 2 } }
);

我正在构建一个查询以向我的文档添加一个“订单”字段

{
"_id": {
    "$oid": "5209acfd0de2316335000001"
},
"bookListId": "116ad5af-7cc6-4652-9bb3-aea852e584e8",
"favoriteBook": [
    {
        "title": "One Favorite Book",
    },
    {
        "title": "Another Favorite Book",
    },
    {
        "title": "A Third Favorite Book",
    }
]
}

..并在 PHP 中使用

$criteria = array('bookListId' => $bookListId);

$favoriteBookOrder = array();

for($i=0;$i<sizeof($order);$i++) {
    $key = 'favoriteBook.'.($i+1).'.order';
    $val = $order[$i];
    $favoriteBookOrder[] = array($key=>intval($val));
}

$setFavoriteBookOrder = array('$set' => $favoriteBookOrder);
$collection->update($criteria, $setFavoriteBookOrder);

但这不会产生任何结果,因为查询没有正确的数组组织..

error_log(json_encode($setupdated));

输出

{"$set":[{"favoriteBook.1.order":2},{"favoriteBook.2.order":1},{"favoriteBook.3.order":3}]}

如果你注意到有太多的引号,整个数组周围的括号,以及每个项目周围的花括号。我相信这是导致错误的原因:

"Invalid modifier specified: $set"

在 PHP 中构建数组的正确语法是什么?谢谢!

编辑

这是修复

$favoriteBookOrder[] = array($key=>intval($val));

should be 

$favoriteBookOrder[$key] = intval($val);

我也从 $i 中删除了 +1,因为 Mongo 索引是基于 0 的

现在正确查询

{"$set":{"favoriteBook.0.order":1,"favoriteBook.1.order":2,"favoriteBook.2.order":3}}
4

1 回答 1

3

为了让您查询工作正常,您必须更改一行:

 $favoriteBookOrder[] = array($key=>intval($val));

 $favoriteBookOrder[$key] = intval($val);

但我认为你不会对结果感到满意,因为它会是这样的:

"favoriteBook" : {
    "0" : { "order" : NumberLong(123) },
    "1" : { "order" : NumberLong(321) },
    "2" : { "order" : NumberLong(456) }
}

我建议你用这种方式重写代码:

for($i=0;$i<sizeof($order);$i++)
    $favoriteBookOrder[$i]['order'] = $order[$i];

$setupdated = array('$set' => ['favoriteBookOrder' => $favoriteBookOrder]);

你会得到:

"favoriteBookOrder" : [
    { "order" : NumberLong(123) },
    { "order" : NumberLong(321) },
    { "order" : NumberLong(456) }
]

PS你可以玩$pushAll修改器而不是$set,它可能更适合你。

于 2013-08-13T05:54:01.407 回答