0

我收到一个错误

Array
(
    [errmsg] => exception: the $unwind field path must be specified as a string
    [code] => 15981
    [ok] => 0
)

虽然我对给定的嵌入式文档使用以下查询(我想从给定的表结构记录中求和 rate_number 的总和)

global $DB, $mongo;
$theObjId = new MongoId($post_id);
$collection = $mongo->getCollection('mongo_hw_posts');

$rt_sum = $collection->aggregate(
    array('$unwind'=>$rate),
    array('$group'=>
        array(
            '_id' => $theObjId
        ),
        array(
            'rate_number'=>array('$sum' =>$rate.'rate_number')
        ))
);

表结构

 {
   "_id": ObjectId("51ff3b38636e3b9803000001"),
   "class_id": NumberInt(2986),
   "created_by": NumberInt(1758),
   "created_datetime": NumberInt(1375681336),
   "deleted": NumberInt(0),
   "learn": {
     "0": {
       "user_id": NumberInt(0),
       "learn_date": NumberInt(0)
    }
  },
   "parent_id": "0",
   "post_text": "2%20C",
   "post_type": "text_comment",
   "rate": {
     "0": {
       "user_id": NumberInt(0),
       "rate_date": NumberInt(0),
       "rate_number": NumberInt(0)
    },
     "1": {
       "user_id": NumberInt(1457),
       "rate_date": NumberInt(1375764137),
       "rate_number": NumberInt(3)
    },
     "2": {
       "user_id": NumberInt(1619),
       "rate_date": NumberInt(1375764694),
       "rate_number": NumberInt(8)
    }
  },
   "serialized_data": "",
   "unique_key": "8bdddfe8137d14702b4517f7e8e88ee3",
   "user_role": "student"
}   
4

1 回答 1

5

您的聚合命令有一些问题。

$放松

代替:

array( '$unwind' => $rate ),

你需要使用:

array( '$unwind' => '$rate'),

$rate不仅仅是一个 PHP 变量,而是 MongoDB中的字段值表达式。

但是你也不能$unwind这样使用,因为:

"errmsg" : "异常:$unwind 字段路径 '$rate' 末尾的值必须是一个数组,但它是一个对象",

那是因为rate是:

"rate": {
    "0": {
       "user_id": NumberInt(0),
       "rate_date": NumberInt(0),
       "rate_number": NumberInt(0)
    },
    "1": {
       "user_id": NumberInt(1457),
       "rate_date": NumberInt(1375764137),
       "rate_number": NumberInt(3)
    },
    "2": {
       "user_id": NumberInt(1619),
       "rate_date": NumberInt(1375764694),
       "rate_number": NumberInt(8)
    }
}

但它需要看起来像:

"rate": [
    {
       "user_id": NumberInt(0),
       "rate_date": NumberInt(0),
       "rate_number": NumberInt(0)
    },
    {
       "user_id": NumberInt(1457),
       "rate_date": NumberInt(1375764137),
       "rate_number": NumberInt(3)
    },
    {
       "user_id": NumberInt(1619),
       "rate_date": NumberInt(1375764694),
       "rate_number": NumberInt(8)
    }
]

否则,$unwind将无法正常工作。为此,您需要更改您的文件。

$组

$group也错了,而不是:

array('$group'=>
    array(
        '_id' => $theObjId
    ),
    array(
        'rate_number'=>array('$sum' =>$rate.'rate_number')
    )
)

您需要使其语法明智:

array('$group'=>
    array(
        '_id' => $theObjId
        'rate_number'=>array('$sum' => '$rate.rate_number')
    )
)

我不明白你为什么有:

'_id' => $theObjId

您是否只想总结一篇文章的费率?如果是这种情况,您将需要添加 a$match并将其更改$theObjId为 null,如下所示:

$rt_sum = $collection->aggregate(
    array( '$match' => array( '_id' => $theObjId ) ),
    array( '$unwind' => '$rate' ),
    array( '$group'=>
        array(
            '_id' => null,
            'rate_number' => array('$sum' => '$rate.rate_number')
        )
    )
);

完整的例子在这里:

<?php
$m = new MongoClient;

$c = $m->test->so;
$c->drop();

$post_id = "51ff3b38636e3b9803000001";

$theObjId = new MongoId($post_id);

$c->insert( array(
    "_id" => new MongoId("51ff3b38636e3b9803000001"),
    "class_id" => 2986,
    "created_by" => 1758,
    "created_datetime" => 1375681336,
    "deleted" => 0,
    "learn" => array(
        array(
            "user_id" => 0,
            "learn_date" => 0
        )
    ),
    "parent_id" => "0",
    "post_text" => "2%20C",
    "post_type" => "text_comment",
    "rate" => array(
        array(
            "user_id" => 0,
            "rate_date" => 0,
            "rate_number" => 0
        ),
        array(
            "user_id" => 1457,
            "rate_date" => 1375764137,
            "rate_number" => 3
        ),
        array(
            "user_id" => 1619,
            "rate_date" => 1375764694,
            "rate_number" => 8
        )
    ),
    "serialized_data" => "",
    "unique_key" => "8bdddfe8137d14702b4517f7e8e88ee3",
    "user_role" => "student"
) );

$rt_sum = $c->aggregate(
    array( '$match' => array( '_id' => $theObjId ) ),
    array( '$unwind' => '$rate' ),
    array( '$group'=>
        array(
            '_id' => null,
            'rate_number' => array('$sum' => '$rate.rate_number')
        )
    )
);

var_dump ($rt_sum);

输出是:

array(2) {
    'result' =>
    array(1) {
        [0] =>
        array(2) {
            '_id' => NULL
            'rate_number' => int(11)
        }
    }
    'ok' =>
    double(1)
}
于 2013-08-06T10:19:10.947 回答