我希望按照目标分组,其数据格式低于格式。
[unique_id] => 649083802
[objectives_compleeted_log_queue] => Array (
)
[objectives] => Array (
[37] => Array (
[is_completed] =>
[tasks] => Array (
[56] => Array (
[completed_count] => 0
[actions] => Array (
[0] => 0
)
)
)
)
[96] => Array (
[is_completed] =>
[tasks] => Array (
[123] => Array (
[completed_count] => 0
[actions] => Array (
[0] => 0
)
)
)
)
[97] => Array (
[is_completed] =>
[tasks] => Array (
[124] => Array (
[completed_count] => 0
[actions] => Array (
[0] => 0
)
)
)
)
我需要在上面的例子中为每个目标(37,96,97 ......)分组unique_ids。对不起mongo db
非常新答案 0 :(得分:1)
根据经验,在文档中使用动态字段名称(例如objectives.37
)会降低索引和查询的灵活性。对于初学者,您将无法利用multi-key indexes。
尽管如此,我们可以使用map/reduce来聚合和计算现有架构中的不同ID。为了保持以下示例简洁,我将字段名称缩短为o
,并将数据夹具中的无关数据缩短。
<?php
$m = new Mongo();
$db = $m->test;
$db->foo->drop();
$db->foo->insert(['o' => [36 => [], 63 => [], 64 => []]]);
$db->foo->insert(['o' => [12 => [], 36 => [], 97 => []]]);
$result = $db->command([
'mapreduce' => 'foo',
'map' => new MongoCode('
function() {
for (var key in this.o) emit(key, { count: 1 });
}
'),
'reduce' => new MongoCode('
function(key, values) {
var r = { count: 0 };
values.forEach(function(v) { r.count += v.count; });
return r;
}
'),
'out' => ['inline' => 1]
]);
echo json_encode($result, JSON_PRETTY_PRINT);
在这里,我们在整个集合中执行map函数,在我们处理的o
个对象中发出每个唯一键。每次发射时,我们发出的初始值为{count: 1}
。在映射之后,我们有大量的排放,包括密钥和{count: 1}
对。然后调用我们的reduce方法来处理不同键的这些中间结果。 values
参数中的每个对象都遵循相同的结构(即我们之前发出的相同值),并且我们应该返回相同结构的单个减少值。
此脚本将产生以下输出:
$ php mr.php
{
"results": [
{
"_id": "12",
"value": {
"count": 1
}
},
{
"_id": "36",
"value": {
"count": 2
}
},
{
"_id": "63",
"value": {
"count": 1
}
},
{
"_id": "64",
"value": {
"count": 1
}
},
{
"_id": "97",
"value": {
"count": 1
}
}
],
"timeMillis": 17,
"counts": {
"input": 2,
"emit": 6,
"reduce": 1,
"output": 5
},
"ok": 1
}
如果您重新设计了模式,以便objectives
是嵌套对象的数组,我们可以利用MongoDB 2.2+中的aggregation framework来更轻松地计算相同的结果:< / p>
<?php
$m = new Mongo();
$db = $m->test;
$db->foo->drop();
$db->foo->insert(['o' => [['id' => 36], ['id' => 63], ['id' => 64]]]);
$db->foo->insert(['o' => [['id' => 12], ['id' => 36], ['id' => 97]]]);
$result = $db->command([
'aggregate' => 'foo',
'pipeline' => [
['$project' => ['o' => 1]],
['$unwind' => '$o'],
['$group' => ['_id' => '$o.id', 'count' => ['$sum' => 1]]],
],
]);
echo json_encode($result, JSON_PRETTY_PRINT);
在这里,我们使用聚合管道按顺序执行三个操作:
o
字段,类似于在查找查询中选择特定输出字段。o
数组。将管道视为文档流,我们将有两个文档进入此步骤,每个文档在各自的o
字段中有三个嵌套对象。展开将产生六个文档到下一步,每个o
数组字段被数组的元素替换。o.id
字段作为分组标识符,并将总和作为每个元素的组值。对于每个分组元素,count
值字段将增加一个。此脚本生成输出:
$ php af.php
{
"result": [
{
"_id": 12,
"count": 1
},
{
"_id": 63,
"count": 1
},
{
"_id": 97,
"count": 1
},
{
"_id": 64,
"count": 1
},
{
"_id": 36,
"count": 2
}
],
"ok": 1
}