我有集合db.problems
。每个文档都包含嵌套的area
和category
个对象。文档的例子:
{
_id: 1,
text: 'Hello',
area: {_id: 23, title: 'Area 61'},
category: {_id: 12, title: 'Just a category'}
}
我正在尝试按类别计算每个区域的问题,并得到类似的结果:
[
{
area: {_id: 2, title: 'Area 61'},
categoriesStats: {
12: {title: 'Just a category', problemCount: 123},
42: {title: 'Another category', problemCount: 11}
}
},
{...}
]
主要的是categoriesStats
必须是哈希(将类别的id作为键)
我现在的目标是什么:
db.problems.aggregate([
{$group: {
_id: {areaId: '$area._id', categoryId: '$category._id'},
problemCount: {$sum: 1},
area: {$first: '$area'},
category: {$first: '$category'}
}},
{$group: {
_id: '$_id.areaId',
area: {$first: '$area'},
categoriesStats: {
$push: {
problemCount: '$problemCount',
category: '$category'
}
}
}},
{$project: {_id: 0, area: 1, categoriesStats: 1}}
])
此查询的结果:
{
"result": [
{
"area": {"_id": 37, "name": "Some area"},
"categoriesStats": [
{
"problemCount": 1,
"category": {"_id": 4, "title": "Just a cat"}
},
{
"problemCount": 1,
"category": {"_id": 3, "title": "Misc"}
}
]
},
{
"area": {"_id": 36, "name": "wow such area"},
"categoriesStats": [
{
"problemCount": 1,
"category": {"_id": 4, "title": "Just a cat"}
},
{
"problemCount": 2,
"category": {"_id": 3, "title": "Misc"}
}
]
}
],
"ok": 1
}
正如您所看到的,我已经设法获得了几乎所需的结果,但我无法将categoriesStats
作为哈希值。
我在$project
阶段尝试过查询
{$project: {'$category._id': '$categories'}
,但
“$ project的顶层不允许使用$表达式”
此外,我也试图像这样预定义查询:
(3
是某类别的_id
)
{$group: ...},
{$project: {
'categoriesStats.3': {$cond: [{$eq: ['$category._id', 3]}, '$category', null]}},
//Same field for every category _id
{$group: ...}
但在这种情况下,我无法通过$group
阶段
所以,问题是,无论如何要以 hashmap 形式获取categoriesStats
吗?
答案 0 :(得分:2)
您可以使用游标方法 forEach()
修改聚合的结果,以迭代游标并访问文档,如下例所示:
var cur = db.problems.aggregate([
{$group: {
_id: {areaId: '$area._id', categoryId: '$category._id'},
problemCount: {$sum: 1},
area: {$first: '$area'},
category: {$first: '$category'}
}},
{$group: {
_id: '$_id.areaId',
area: {$first: '$area'},
categoriesStats: {
$push: {
problemCount: '$problemCount',
category: '$category'
}
}
}},
{$project: {_id: 0, area: 1, categoriesStats: 1}}
]),
results = [];
cur.forEach(function (res){
var obj = {
"categoriesStats": {}
};
var category = {};
obj.area = res.area;
res.categoriesStats.forEach(function(c){
var cat = {};
cat["title"] = c.category.title;
cat["problemCount"] = c.problemCount;
obj["categoriesStats"][c.category._id.toString()] = cat;
});
results.push(obj);
});
查看下面的演示
var cur = {
"result": [
{
"area": {"_id": 37, "name": "Some area"},
"categoriesStats": [
{
"problemCount": 1,
"category": {"_id": 4, "title": "Just a cat"}
},
{
"problemCount": 1,
"category": {"_id": 3, "title": "Misc"}
}
]
},
{
"area": {"_id": 36, "name": "wow such area"},
"categoriesStats": [
{
"problemCount": 1,
"category": {"_id": 4, "title": "Just a cat"}
},
{
"problemCount": 2,
"category": {"_id": 3, "title": "Misc"}
}
]
}
],
"ok": 1
};
var results = [];
cur.result.forEach(function (doc){
var obj = {
"categoriesStats": {}
};
var category = {};
obj.area = doc.area;
doc.categoriesStats.forEach(function(c){
var cat = {};
cat["title"] = c.category.title;
cat["problemCount"] = c.problemCount;
obj["categoriesStats"][c.category._id.toString()] = cat;
});
results.push(obj);
});
pre.innerHTML = JSON.stringify(results);

<pre id="pre"></pre>
&#13;