在包含数组的文档上使用聚合?

时间:2014-12-24 18:37:27

标签: mongodb

我有一个包含以下结构的文档的集合:

{
   answers: [
      {
          Title: 'What's your age?',
          values: [
                      {value: true, label: '18-30'}
                  ]
      },
      {
          Title: 'What's your favorite color(s)?',
          values: [
                      {value: true, label: 'Red'},
                      {value: true, label: 'Green'}
                  ]
      }
   ]
},
{
   answers: [
      {
          Title: 'What's your age?',
          values: [
                      {value: true, label: '31-40'}
                  ]
      },
      {
          Title: 'What's your favorite color(s)?',
          values: [
                      {value: true, label: 'Red'}
                  ]
      }
   ]
}

我想得到各种答案的计数。所以对于上面的数据,我想得到类似的东西:

{
   {
      Title: "What's your age?",
      AgeTotals: {
        "18-30": 1,
        "31-40": 1
      }
   },
   {
      Title: "What's your favorite color(s)?",
      ColorTotals: {
        "Red": 2,
        "Green": 1
      }
   }
}

我的第一个想法是做这样的事情:

db.test.aggregate(
    {$unwind: "$answers"},
    {$unwind: "$answers.values"},
    {$group:{
        _id: "$answers.values.label",
        totals: {$sum: 1}
        }
    }
);

但这会产生输出:

{ "_id" : "31-40", "totals" : 1 }
{ "_id" : "Red", "totals" : 2 }
{ "_id" : "Green", "totals" : 1 }
{ "_id" : "18-30", "totals" : 1 }

我如何获得每个答案的总数而不是上述答案?

更新:

如果数据以下列格式输出,我也没问题:

{ "title: "What's your age?", "_id" : "31-40", "totals" : 1 }
{ "title": "What's your favorite color?", "_id" : "Red", "totals" : 2 }
{ "title": "What's your favorite color?", "_id" : "Green", "totals" : 1 }
{ "title: "What's your age?", "_id" : "18-30", "totals" : 1 }

2 个答案:

答案 0 :(得分:3)

你非常接近。

  • 您需要将answers.Title添加到第一个组_id才能获得它 列在文件上。
  • Group记录再次基于答案标题,和 使用$push运算符累计各种标签的计数。

更新代码:

db.test.aggregate([
    {$unwind: "$answers"},
    {$unwind: "$answers.values"},
    {$group:{"_id": {"answer":"$answers.Title",
                     "label":"$answers.values.label"},
              "totals": {$sum: 1}}
    },
    {$group:{"_id":"$_id.answer",
             "totals":{$push:{"label":"$_id.label",
                              "count":"$totals"}}}} 
]); 

样本o / p:

{
        "_id" : "What's your favorite color(s)?",
        "totals" : [
                {
                        "label" : "Green",
                        "count" : 1
                },
                {
                        "label" : "Red",
                        "count" : 2
                }
        ]
}
{
        "_id" : "What's your age?",
        "totals" : [
                {
                        "label" : "31-40",
                        "count" : 1
                },
                {
                        "label" : "18-30",
                        "count" : 1
                }
        ]
}

当你说,你想获得以下输出:

{
   {
      Title: "What's your age?",
      AgeTotals: {
        "18-30": 1,
        "31-40": 1
      }
   },
   {
      Title: "What's your favorite color(s)?",
      ColorTotals: {
        "Red": 2,
        "Green": 1
      }
   }
}

您注意到输出包含value字段作为其key。 (字段标签的值 - “红色”,是一个键。)。聚合框架有限制,其中一个限制是来自字段的值无法转换为输出文档中的键。为此,您需要执行map-reduce。

答案 1 :(得分:1)

您可以选择其他输出:

db.test.aggregate([
{"$unwind": "$answers"},
{"$group": {'_id': {"title": "$answers.Title", "value": "$answers.values.label" }}},
{"$unwind": "$_id.value"},
{"$group": {"_id": {"title": "$_id.title", "value": "$_id.value"}, "total": {"$sum": 1}}},
{"$project": {"title": "$_id.title", "value": "$_id.value", "total": 1, "_id": 0}}])

产生:

{
    "result" : [ 
        {
            "total" : 1,
            "title" : "What's your age?",
            "value" : "18-30"
        }, 
        {
            "total" : 1,
            "title" : "What's your favorite color(s)?",
            "value" : "Green"
        }, 
        {
            "total" : 2,
            "title" : "What's your favorite color(s)?",
            "value" : "Red"
        }, 
        {
            "total" : 1,
            "title" : "What's your age?",
            "value" : "31-40"
        }
    ],
    "ok" : 1
}

此输出具有一致性结构的优点,其中仅将元数据存储为键。

相关问题