如何计算mongodb中嵌套文档中的出现次数?

时间:2013-12-31 02:28:25

标签: mongodb mongodb-query aggregation-framework

如果数组嵌套在数组中,我如何计算特定值的数量?例如,我想在下面的文档中计算“答案”的数量。查询应该返回有2个苹果和1个香蕉。

{
  "_id" : ObjectId("52c1d909fc7fc68ddd999a73"),
  "name" : "Some survey",
  "questions" : [
    {
      "_id" : ObjectId("52c1e250fc7fc68ddd999a75"),
      "answers" :
      [
        {
          "userId" : "some GUIDs",
          "answer" : "apple"
        },
        {
          "userId" : "some GUID",
          "answer" : "apple"
        },
        {
          "userId" : "some GUID",
          "answer" : "banana"
        }
      ],
      "questionText" : "blah blah blah...",
      "questionType" : "multiple choice"
    }
]

}

2 个答案:

答案 0 :(得分:4)

根据您需要处理的数据量,有几种方法可以解决这个问题。您可以在MongoDB 2.2+中使用Aggregation Framework,也可以使用Map/Reduce。有关功能和限制的摘要,请参阅Aggregation Commands Comparison

以下是使用聚合框架的示例:

db.fruit.aggregate(
    // Limit matching documents (can take advantage of index)
    { $match: {
        "_id" : ObjectId("52c1d909fc7fc68ddd999a73")
    }},

    // Unpack the question & answer arrays
    { $unwind: "$questions" },
    { $unwind: "$questions.answers" },

    // Group by the answer values
    { $group: {
        _id: "$questions.answers.answer",
        count: { $sum: 1 }
    }}
)

对于您的示例文档,它将返回:

{
    "result" : [
        {
            "_id" : "banana",
            "count" : 1
        },
        {
            "_id" : "apple",
            "count" : 2
        }
    ],
    "ok" : 1
}

答案 1 :(得分:0)

这是使用聚合框架为您的猫设置皮肤的一种方法。一旦你学会了它,你可以用你的数据做很多好事。

db.so.aggregate([{$unwind:"$questions"}, {$unwind:"$questions.answers"}, {$group:{_id:"$questions.answers.answer", fruit_count:{$sum:1}}}])

给我这个:

{
    "result" : [
        {
            "_id" : "banana",
            "fruit_count" : 1
        },
        {
            "_id" : "apple",
            "fruit_count" : 2
        }
    ],
    "ok" : 1

为了倍加肯定,我添加了这个文档:

db.so.insert({
  "_id" : ObjectId("52c1d909fc7fc68ddd999a75"),
  "name" : "Some survey",
  "questions" : [
    {
      "_id" : ObjectId("52c1e250fc7fc68ddd999a75"),
      "answers" :
      [
        {
          "userId" : "some GUIDs",
          "answer" : "orange"
        },
        {
          "userId" : "some GUID",
          "answer" : "orange"
        },
        {
          "userId" : "some GUID",
          "answer" : "banana"
        }
      ],
      "questionText" : "blah blah blah...",
      "questionType" : "multiple choice"
    }
]
})

我的查询现在给了我:

{
    "result" : [
        {
            "_id" : "orange",
            "fruit_count" : 2
        },
        {
            "_id" : "banana",
            "fruit_count" : 2
        },
        {
            "_id" : "apple",
            "fruit_count" : 2
        }
    ],
    "ok" : 1
}