我有一个存储在mongodb中的记录数据集,我一直在尝试从记录中提取一组复杂的数据。
样本记录如下: -
{
bookId : '135wfkjdbv',
type : 'a',
store : 'crossword',
shelf : 'A1'
}
{
bookId : '13erjfn',
type : 'b',
store : 'crossword',
shelf : 'A2'
}
我一直在尝试提取数据,以便每个bookId,我得到每个商店名称的每个货架的计数(记录),其中包含bookId标识的书籍,其中书籍的类型是' a&# 39;
我知道聚合查询允许管道允许分组,匹配等,但我无法达成解决方案。
所需的输出格式为: -
{
bookId : '135wfkjdbv',
stores : [
{
name : 'crossword'
shelves : [
{
name : 'A1',
count : 12
},
]
},
{
name : 'granth'
shelves : [
{
name : 'C2',
count : 12
},
{
name : 'C4',
count : 12
},
]
}
]
}
答案 0 :(得分:0)
当你看到这个过程并不是那么困难。聚合“管道”就是这样,每个“阶段”将结果输入下一个进行处理。就像unix“pipe”:
ps -ef | grep mongo | tee out.txt
所以它只是添加阶段,实际上是三个$group
阶段,其中第一阶段进行基本聚合,其余两阶段简单地“汇总”输出中所需的数组。
db.collection.aggregate([
{ "$group": {
"_id": {
"bookId": "$bookId",
"store": "$store",
"shelf": "$shelf"
},
"count": { "$sum": 1 }
}},
{ "$group": {
"_id": {
"bookId": "$_id.bookId",
"store": "$_id.store"
},
"shelves": {
"$push": {
"name": "$_id.shelf",
"count": "$count"
}
}
}},
{ "$group": {
"_id": "$_id.bookId",
"stores": {
"$push": {
"name": "$_id.store",
"shelves": "$shelves"
}
}
}}
])
最后你可能会$project
将_id
更改为bookId
,但你应该已经知道它是什么,并习惯于将_id
视为$group
主键。这样的操作需要付出代价,所以这是一种习惯,你不应该从一开始就学习正确的事情。
所以这里真正发生的是,构成分组细节的所有字段都成为count
的主键,而另一个字段被生成为GROUP BY bookId, store, shelf
,以计算其中的架子分组。想想SQL等价物:
{{1}}
所有其他阶段都将每个分组级别转换为数组条目,首先是商店内的货架,然后是bookId中的商店。每次主要分组键中的字段都会被进入生成数组的内容减少。
当你开始考虑“管道”处理时,它就变得清晰了。在构造一个表单时,然后获取该输出并将其移动到下一个表单,依此类推。这基本上就是如何在两个数组中折叠结果。