2

想象一下,我有一个包含以下文档的 MonogDB 集合:

{name: 'Some Name', components: {ARRAY OF ITEMS}}

如何返回组件中项目的名称和数量?我必须使用地图/减少吗?

我正在使用 PHP 的 Mongo 扩展。

编辑:PHP 中当前代码的片段(工作),但我只想计算组件

$fields = array(
    'name', 'components'
);
$cursor = $this->collection->find(array(), $fields);
$cursor->sort(array('created_ts' => -1));

if (empty($cursor) == true) {
    return array();
} else {
    return iterator_to_array($cursor);
}

谢谢,吉姆

4

4 回答 4

1

您可以使用 map-reduce,也可以使用简单的查询,如下所示。由于我假设您的 name 属性是唯一键,因此即使这不是您通常使用 group 函数的原因,这也应该有效:

db.test.group({
 key: { name:true },
 reduce: function(obj,prev) {
  var count = 0;
  for(k in obj.components)
   count++;
  prev.count = count;
 },
 initial: { count: 0}
});

您提到您有一个组件数组,但似乎您将组件存储为对象{}而不是数组[]。这就是为什么我必须在 reduce 函数中添加循环,以计算组件对象的所有属性。如果它实际上是一个数组,那么您可以简单地使用该.length属性。

在 PHP 中,它看起来像这样(来自手册):

$keys = array('name' => 1);
$initial = array('count' => 0);
$reduce =<<<JS
function(obj,prev) {
  var count = 0;
  for(k in obj.components)
   count++;
  prev.count = count;
 },
JS;

$m = new Mongo();
$db = $m->selectDB('Database');
$coll = $db->selectCollection('Collection');
$data = $coll->group($keys, $initial, $reduce);

最后,我强烈建议,如果您尝试定期访问组件的计数,则将计数存储为文档的附加属性,并在更改时更新它。如果您尝试编写基于此计数进行过滤的查询,那么您还可以在该组件属性上添加索引。

于 2011-09-14T16:35:06.247 回答
0

您可以使用db.eval()并用 JavaScript 编写计算。

于 2011-09-13T13:29:30.480 回答
0

吉姆-

这是两个独立的操作;除非您想利用 PHP 对您获得的结果的计数,否则您将执行以下操作:

$m = new Mongo();
$db = $m->selectDB('yourDB');
$collection = $db->selectCollection('MyCollection');
$cursor = $collection->find(array(), array("name"=>1, "components"=>1));
foreach($cursor as $key){
   echo($key['name'].' components: '.count($key['components']);
}
于 2011-09-13T13:16:18.223 回答
0
于 2016-08-31T21:00:44.573 回答