php& mongodb:使用$ addToSet w / $ each

时间:2013-07-25 22:11:30

标签: mongodb mongodb-php

这个问题与我的问题非常相似:Is there a way to check if one of the array entries contains a sub-array in MongoDB?

然而,在我的情况下,我仍然遇到一些更新问题。 我通过引入标签的聚合器获取数据。 标签看起来像这个$tags = array("red","green","blue","purple",...);

我的更新查询如下所示:

$criteria = array('_id' => new MongoId($myID));

$db->aggregation->update($criteria, 
                         array('$addToSet' =>
                            array('tags' =>
                               array('$each' => $tags)))), 
                         true); //add tags

信不信由你,有时它会游泳,但有时却没有。 您可以在下面的示例中看到哪些有效,哪些无效。

[74] => red
[75] => orange
[76] => yellow
[77] => green
[78] => Array (
    [$each] => Array (
        [0] => blue
        [1] => indigo
        [2] => purple
    )
)
[79] => violet
[80] => brown
[81] => black

有人可以向我解释为什么有时这会正确地插入到集合的数组中,有时它不会? 我正在使用phpmoadmin(以及MongoDB shell版本2.4.3'find()')来查看插入的结果。

1 个答案:

答案 0 :(得分:0)

对于初学者,将布尔值作为第三个参数传递给MongoCollection::update()在1.3.0中已弃用。在下面的示例中,我使用现在建议的$options数组作为该方法的第三个也是最后一个参数。

您是否可以验证示例中第78个数组元素的$each键是否恰好是那5个字符,并且不包含前导不可打印的字符?如果我在$each前加chr(13)(即换页),那么MongoDB并没有使用运算符来接收我,并且很乐意将对象参数添加到集合/数组中。

除此之外,我能够重现上述内容的唯一方法是制作一个更新,其中$each的值是一个对象:

$c->update(
  ['_id'=>1],
  ['$addToSet' => [
    'tags' => ['$each' => (object) [1,2,3,4,5]],
  ]],
  ['upsert' => true]
);

这导致插入以下内容(使用Mongo shell,以便我们可以区分数组和对象):

{
    "_id" : NumberLong(1),
    "tags" : [
        {
            "$each" : {
                "0" : NumberLong(1),
                "1" : NumberLong(2),
                "2" : NumberLong(3),
                "3" : NumberLong(4),
                "4" : NumberLong(5)
            }
        }
    ]
}

如果其他元素已经在tags中,则上述内容可能会进一步进入数组,如下所示:

{
    "_id" : NumberLong(1),
    "tags" : [
        NumberLong(1),
        NumberLong(2),
        NumberLong(3),
        NumberLong(4),
        NumberLong(5),
        {
            "$each" : {
                "0" : NumberLong(1),
                "1" : NumberLong(2),
                "2" : NumberLong(3),
                "3" : NumberLong(4),
                "4" : NumberLong(5)
            }
        }
    ]
}