4

我有一个MongoDB可以通过 MongoDB shell 运行的有效聚合查询。但是,我正在尝试将其转换为与官方PHPMongo 驱动程序(http://php.net/manual/en/mongocollection.aggregate.php)一起使用。

这是工作的原始 MongoDB 查询:

db.executions.aggregate( [  
   { $project : { day : { $dayOfYear : "$executed" } } },
   { $group : { _id : { day : "$day" }, n : { $sum : 1 } } } , 
   { $sort : { _id : -1 } } , 
   { $limit : 14 }
] )

这是我使用 Mongo 驱动程序的尝试(不工作) :PHP

$result = $c->aggregate(array(
    '$project' => array(
        'day' => array('$dayOfYear' => '$executed')
    ),
    '$group' => array(
        '_id' => array('day' => '$day'),
        'n' => array('$sum' => 1)
    ),
    '$sort' => array(
        '_id' => 1
    ),
    '$limit' => 14
));

上述 PHP 代码的错误是:

{"errmsg":"exception: wrong type for field (pipeline) 3 != 4","code":13111,"ok":0}

有任何想法吗?谢谢。

4

2 回答 2

18

您的 Javascript 中的参数是一个由 4 个对象组成的数组,每个对象有一个元素,在您的 PHP 中,它是一个具有 4 个元素的关联数组(对象)。这将代表您的 Javascript:

$result = $c->aggregate(array(
    array(
      '$project' => array(
          'day' => array('$dayOfYear' => '$executed')
      ),
    ),
    array(
      '$group' => array(
          '_id' => array('day' => '$day'),
          'n' => array('$sum' => 1)
      ),
    ),
    array(
      '$sort' => array(
          '_id' => 1
      ),
    ),
    array(
      '$limit' => 14
    )
));

另外,如果你至少有 PHP5.4,你可以使用更简单的数组语法。转换为 PHP 就很简单了,您只需将花括号替换为方括号,将冒号替换为箭头:

$result = $c->aggregate([
  [ '$project' => [ 'day' => ['$dayOfYear' => '$executed']  ]  ],
  [ '$group' => ['_id' => ['day' => '$day'], 'n' => ['$sum' => 1]  ] ],
  [ '$sort' => ['_id' => 1] ],
  [ '$limit' => 14 ]
]);
于 2013-01-03T01:27:12.823 回答
0

也可以直接使用 JSON 数组:

$json = [
  '{ $project : { day : { $dayOfYear : "$executed" } } },
   { $group : { _id : { day : "$day" }, n : { $sum : 1 } } } , 
   { $sort : { _id : -1 } } , 
   { $limit : 14 }'
];

$pipeline = [];
foreach ($json as $stage) {
   array_push($pipeline, toPHP(fromJSON($stage)));
}
$result = $c->aggregate($pipeline);

您也可以像这样使用组合:

use function MongoDB\BSON\toRelaxedExtendedJSON;
use function MongoDB\BSON\fromPHP;
use function MongoDB\BSON\toPHP;
use function MongoDB\BSON\fromJSON;

$operator = '$dayOfYear';
$json = [];
array_push($json, toRelaxedExtendedJSON(fromPHP(
   array('$project ' => array('day' => array($operator => '$executed')))
)));
array_push($json, 
   '{ $group : { _id : { day : "$day" }, n : { $sum : 1 } } } , 
    { $sort : { _id : -1 } } , 
    { $limit : 14 }'
);
$pipeline = [];
foreach ($json as $stage) {
   array_push($pipeline, toPHP(fromJSON($stage)));
}
$result = $c->aggregate($pipeline);

或者

$operator = '$dayOfYear';
$json = [];
array_push($json, 
   '{ $group : { _id : { day : "$day" }, n : { $sum : 1 } } } , 
    { $sort : { _id : -1 } } , 
    { $limit : 14 }'
);
$pipeline = [];
array_push($pipeline, array('$project ' => array('day' => array($operator => '$executed'))));
foreach ($json as $stage) {
   array_push($pipeline, toPHP(fromJSON($stage)));
}
$result = $c->aggregate($pipeline);

如果您的聚合查询是动态的或基于用户输入的,请注意 NoSQL-Injection! https://www.acunetix.com/blog/web-security-zone/nosql-injections/

于 2022-01-11T16:15:49.090 回答