MongoDB 嵌套分组?

22

我正在尝试在MongoDB中实现嵌套分组查询,但是我卡在了尝试添加外部分组的地方。给定以下(简化的)数据文档:

{
  "timestamp" : ISODate(),
  "category" : "movies",
  "term" : "my movie"
}

我正在尝试获取所有类别的列表,并且在类别内应该有顶部数量的术语。我希望我的输出类似于这样:

[
 { category: "movies", 
   terms: [ { term: "movie 1", total: 5000 }, { term: "movie 2", total: 200 } ... ]
 },
 { category: "sports", 
   terms: [ { term: "football 1", total: 4000 }, { term: "tennis 2", total: 250 } ... ]
 },
]

我的“内部组”如下所示,并将为所有类别获取前5名:

db.collection.aggregate([
    { $match : { "timestamp": { $gt: ISODate("2014-08-27") } } },
    { $group : { _id :  "$term", total : { $sum : 1 } } },
    { $sort : { total : -1 } },
    { $limit: 5 }
]);

// Outputs:
{ "_id" : "movie 1", "total" : 943 }
{ "_id" : "movie 2", "total" : 752 }

如何实现“外部分组”?

另外,有时上述聚合返回空值(并非所有文档都具有术语值)。如何忽略空值?

提前致谢。

2个回答

46
在这种情况下,您需要两个组。第一个组按术语和类别生成文档流,每个术语和类别生成一个文档:
 { $group : { 
      _id :  { 
        category: "$category",
        term: "$term",
      },
      total: { $sum : 1 } 
   }
 }

接下来,第二个组将使用$push操作符将所有具有相同词项的文档合并为一个,并将类别合并到一个数组中:

 { $group : { 
      _id :  "$_id.category",
      terms: { 
          $push: { 
              term:"$_id.term",
              total:"$total"
          }
      }
   }
 }

2
谢谢!这解决了我的问题,我在两个分组之间添加了 { $sort : { total : -1 } } 以确保最多的分组术语在顶部,但我无法弄清如何限制每个类别的术语为5个。在分组之间添加 { $limit: 6 } 不起作用。(我正在尝试执行每个类别的前5个术语查询)。谢谢! - clangers
也帮助了我!太神奇了! - Alex Ward

7

查询:

    db.getCollection('orders').aggregate([
    {$match:{
        tipo: {$regex:"[A-Z]+"}
        }
    },
    {$group:
        { 
            _id:{
                codigo:"1",
                tipo:"$tipo",
            },
            total:{$sum:1}
        }
    },
    {$group:
        {
            _id:"$_id.codigo",
            tipos:
            {
                $push:
                {
                    tipo:"$_id.tipo",
                    total:"$total"
                }
            },
            totalGeneral:{$sum:"$total"}

        }

    }


]);

响应:

{
"_id" : "1",
"tipos" : [ 
    {
        "tipo" : "TIPO_01",
        "total" : 13.0
    }, 
    {
        "tipo" : "TIPO_02",
        "total" : 2479.0
    }, 
    {
        "tipo" : "TIPO_03",
        "total" : 12445.0
    }, 
    {
        "tipo" : "TIPO_04",
        "total" : 12445.0
    }, 
    {
        "tipo" : "TIPO_05",
        "total" : 21.0
    }, 
    {
        "tipo" : "TIPO_06",
        "total" : 21590.0
    }, 
    {
        "tipo" : "TIPO_07",
        "total" : 1065.0
    }, 
    {
        "tipo" : "TIPO_08",
        "total" : 562.0
    }
],
"totalGeneral" : 50620.0

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接