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

Mongodb 在包含数组的文档上使用聚合?,mongodb,Mongodb,我有一个包含如下结构的文档的集合: { answers: [ { Title: 'What's your age?', values: [ {value: true, label: '18-30'} ] }, { Title: 'What's your favorite color(s)?', v

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

{
   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 }
你很接近

  • 您需要将
    答案。Title
    添加到第一组
    \u id
    ,才能获得答案 在文件上列出
  • 根据答案标题再次分组
    记录,以及 使用运算符累积各种标签的计数
更新代码:

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"}}}} 
]); 
订单样本:

{
        "_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
      }
   }
}
您注意到输出包含一个
字段作为其
。(字段标签“红色”的值是一个键。)。聚合框架有一些限制,其限制之一是字段中的值不能转换为输出文档中的键。要实现这一点,您需要执行map reduce。

您已经非常接近了

  • 您需要将
    答案。Title
    添加到第一组
    \u id
    ,才能获得答案 在文件上列出
  • 根据答案标题再次分组
    记录,以及 使用运算符累积各种标签的计数
更新代码:

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"}}}} 
]); 
订单样本:

{
        "_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
      }
   }
}

您注意到输出包含一个
字段作为其
。(字段标签“红色”的值是一个键。)。聚合框架有一些限制,其限制之一是字段中的值不能转换为输出文档中的键。要实现这一点,您需要执行map reduce。

对于可选输出,您可以执行以下操作:

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
}

此输出具有一致性结构的优点,其中只有元数据存储为密钥

对于可选输出,您可以执行以下操作:

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
}
此输出具有一致性结构的优点,其中只有元数据存储为密钥