聚合输出到Nest Arrays

时间:2015-09-29 15:29:31

标签: javascript mongodb mongodb-query aggregation-framework

我有一个存储在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
                },
           ]
       }  
   ]
}

1 个答案:

答案 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中的商店。每次主要分组键中的字段都会被进入生成数组的内容减少。

当你开始考虑“管道”处理时,它就变得清晰了。在构造一个表单时,然后获取该输出并将其移动到下一个表单,依此类推。这基本上就是如何在两个数组中折叠结果。