Node.js 如何将数据聚合到嵌套数组输出
我收集了以下数据 {“UID”:567,“AN0:100,“AN1:150,历代:1401399336437}Node.js 如何将数据聚合到嵌套数组输出,node.js,mongodb,aggregation-framework,Node.js,Mongodb,Aggregation Framework,我收集了以下数据 {“UID”:567,“AN0:100,“AN1:150,历代:1401399336437} {“UID”:123,“AN0”:200,“AN1”:250,纪元:1401399336438} {“UID”:567,“AN0:300,“AN1:350,历代:1401399336439} 对于UID:567&&AN0,我希望获得类似以下内容的输出: {键:“AN0”, 值:[ [1401399336437100] [1401399336439300] ] } 我已经或多或少地使用
{“UID”:123,“AN0”:200,“AN1”:250,纪元:1401399336438}
{“UID”:567,“AN0:300,“AN1:350,历代:1401399336439}
对于UID:567&&AN0,我希望获得类似以下内容的输出: {键:“AN0”,
值:[
[1401399336437100]
[1401399336439300]
]
}
我已经或多或少地使用了如下组:
db.Datasets.group({
cond: {UID: "567", AN0:{$exists:true}, epoch:{$exists:true}},
initial: {key:"", values: []},
reduce: function(obj, prev){
var temp =[];
temp.push(obj.epoch);
temp.push(obj.AN0);
prev.values.push(temp);
},
finalize: function(result){
result.key = "AN0";
}
})
然而,在与reduce和finalize函数共享作用域时,这种方法给了我很多问题
因此,我希望对聚合管道也这样做
我试过了
db.Datasets.aggregate( [
{$match:{ UID: "567" , AN0: {$exists:true} }},
{$group : { _id: "$UID", value1: { $push: "$epoch"}, value2: { $push: "$AN0"} }},
] )
我明白了
{value1:[1401399336437,1401399336439],值2:[100300] 如何改变这一点以获得 值:[
[1401399336437100]
[1401399336439300]
]
谢谢!对我来说,我会做一些不同的聚合,然后对结果进行后期处理
var res = db.collection.aggregate([
{ "$group": {
"_id": "$UID",
"value": {
"$push": {
"a": "$epoch", "b": "$AN0"
}
}
}}
]).toArray()
在这个阶段,结果如下所示:
[
{ "_id" : 123, "value" : [ { "a" : 1401399336438, "b" : 200 } ] },
{ "_id" : 567, "value" : [ { "a" : 1401399336437, "b" : 100 }, { a" : 1401399336439, "b" : 300 } ]}
]
现在只需转换:
var res = res.map(function(doc) {
doc.value = doc.value.map(function(x){
return [x.a,x.b]
});
return doc;
})
但是,如果您真的下定决心要这样做,并且MongoDB 2.6可用,那么也总会有这样的方法:
db.collection.aggregate([
{ "$group": {
"_id": "$UID",
"val": {
"$push": {
"a": "$epoch", "b": "$AN0"
}
}
}},
{ "$project": {
"value": {
"$map": {
"input": "$val",
"as": "el",
"in": {
"$map": {
"input": { "$literal": ["A","B"] },
"as": "type",
"in": {
"$cond": [
{ "$eq": [ "$$type", "A" ] },
"$$el.a",
"$$el.b"
]
}
}
}
}
}
}}
])
这里的诀窍在内部语句中。本质上,这将返回一个数组,指定为源输入的文本[“a”,“B”]
。“外部”$map处理从中创建的数组的每个元素,“内部”$map操作处理每个“a”或“B”并测试值
在操作中,如果当前值为“A”,则将外部数组元素的已保留变量作为“A”键值返回,否则返回“b”键值。简而言之,将“外部”中的每个元素替换为替换后的“内部”形式。现在,数组中的数组不再是带键的文档
任何一种情况下的输出都是您想要的:
[
{
"_id" : 123,
"value" : [
[
1401399336438,
200
]
]
},
{
"_id" : 567,
"value" : [
[
1401399336437,
100
],
[
1401399336439,
300
]
]
}
]
从第二个解决方案来看,您似乎很有经验。这个解决方案比mapReduce实现快吗?我之所以希望数据采用这种格式,是因为NVD3图形库可以避免在客户端重新处理数据。@操作码快得多。mapReduce和其他像group这样的操作依赖于JavaScript处理,因为这需要运行通过解释器,它比在本机代码中实现的聚合管道慢得多。