gpt4 book ai didi

php - MongoDB 聚合子数组作为组 _id

转载 作者:可可西里 更新时间:2023-11-01 10:27:42 26 4
gpt4 key购买 nike

我在使用 MongoDB 聚合框架计算数据库中的事件类型时遇到了一些问题。如何为 _id.val 字段的每个唯一第三个索引计算 value.count 字段的总和?

我的数据的基本结构如下:

{ _id: { evt: "click", val: [ "default", "125", "311", "1" ] }, value: { count: 1 } }
{ _id: { evt: "click", val: [ "default", "154", "321", "2" ] }, value: { count: 2 } }
{ _id: { evt: "click", val: [ "default", "192", "263", "1" ] }, value: { count: 4 } }

val 字段中的值分别表示 ["type","x","y","time"]。我正在尝试提取 _id.val 键的第三个索引或 time 值。我希望实现的输出:

 1: 5
2: 2

我一直在尝试通过这个 PHP 来做到这一点:

$ops2 = array(
array(
'$match' => $q2
),
array(
'$group' => array(
'_id' => array(
'evt' => '$_id.evt',
'time' => '$_id.val.3'
),
'count' => array('$sum' => '$value.count' )
)
)
);

但它似乎并不喜欢组数组中的 3 索引

最佳答案

您正在处理的数据看起来就像是 mapReduce 操作的输出,因为它具有 mapReduce 生成的特定“_id”和“value”结构。因此,您最好回到该过程的实现逻辑并遵循相同的逻辑来提取和汇总您想要的内容,或者至少将其输出形式更改为:

{ 
_id: {
evt: "click",
val: { "type": "default", "x": "125", "y": "311", "time": "1" }
},
value: { count: 1 }
},
{
_id: {
evt: "click",
val: { "type": "default", "x": "154", "y": "321", "time": "2" }
},
value: { count: 2 }
},
{
_id: {
evt: "click",
val: { "type": "default", "x": "192", "y": "263", "time": "1" }
},
value: { count: 4 }
}

因为问题是聚合框架“目前”缺乏解决数组“索引”位置的能力(真正的“非关联”数组而不是 PHP 数组)并且总是返回 null 当你尝试这样做时。

缺少返回原始源或 mapReduce 操作的能力,那么您可以在此数据上编写 mapReduce 操作以获得预期结果(shell 表示,因为它无论如何都将是 JavaScript):

db.collection.mapReduce(
function() {
emit({ evt: this._id.evt, time: this._id.val[3] }, this.value.count)
},
function(key,values) {
return Array.sum(values)
},
{ out: { inline: 1 } }
)

返回典型的 mapReduce 输出如下:

{
"_id" : {
"evt" : "click",
"time" : "1"
},
"value" : 5
},
{
"_id" : {
"evt" : "click",
"time" : "2"
},
"value" : 2
}

如果您至少能够将当前输出集合转换为上面首先建议的形式,那么您将使用这样的聚合框架运行(同样是通用表示):

    { "$group": {
"_id": {
"evt": "$_id.evt",
"time": "$_id.val.time"
},
"count": { "$sum": "$value.count" }
}}

当然会从更改后的数据中产生:

{ "_id" : { "evt" : "click", "time" : "2" }, "count" : 2 }
{ "_id" : { "evt" : "click", "time" : "1" }, "count" : 5 }

在 MongoDB 的 future 版本中,将有一个允许数组处理的 $slice 运算符,因此对于您当前的结构,您可以改为这样做:

    { "$group": {
"_id": {
"evt": "$_id.evt",
"time": { "$slice": [ "$_id.val", 3,1 ] }
},
"count": { "$sum": "$value.count" }
}}

这允许从数组中选择“第三个”索引元素,尽管这当然仍然会返回一个“数组”作为这样的元素:

{ "_id" : { "evt" : "click", "time" : [ "2" ] }, "count" : 2 }
{ "_id" : { "evt" : "click", "time" : [ "1" ] }, "count" : 5 }

所以现在,如果您可以更改您的初始 mapReduce 输出,那就去做吧。要么使用此处显示的表单,要么只修改初始查询以获得您想要的最终结果。修改为推荐的形式将至少允许 .aggregate() 命令像此处第二个示例中所示那样工作。

如果不是,那么 mapReduce 仍然是目前唯一的写入方式,如“第一个”示例所示。

关于php - MongoDB 聚合子数组作为组 _id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32150765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com