在数组

时间:2015-05-27 16:51:40

标签: mongodb

我正在尝试对示例bios集合http://docs.mongodb.org/manual/reference/bios-example-collection/制定查询:

检索所有在同一年获得两个奖项的人。

预期答案是" Ole-Johan Dahl"和" Kristen Nygaard"例如,Ole-Johan Dahl的文档是 { "_id" : 5, "name" : { "first" : "Ole-Johan", "last" : "Dahl" }, "birth" : ISODate("1931-10-12T04:00:00Z"), "death" : ISODate("2002-06-29T04:00:00Z"), "contribs" : [ "OOP", "Simula" ], "awards" : [ { "award" : "Rosing Prize", "year" : 1999, "by" : "Norwegian Data Association" }, { "award" : "Turing Award", "year" : 2001, "by" : "ACM" }, { "award" : "IEEE John von Neumann Medal", "year" : 2001, "by" : "IEEE" } ] }

到目前为止,我能提出的最佳查询是使用聚合框架的以下查询:

db.bios.aggregate([ 
    {$project : { "first_name": "$name.first", "last_name": "$name.last" , "award1" :"$awards", "award2" :"$awards" } },
    {$unwind : "$award1"},
    {$unwind : "$award2"},
    {$project : {  "first_name": 1, "last_name": 1, "award1" : 1, "award2" : 1,
    "super" : { $and : [  {$eq : ["$award1.year", "$award2.year"]}, 
        {$lt: ["$award1.award", "$award2.award"]} 
       ]
     }}
    },
    {$match : {"super": true}}
])

但是我对这个解决方案不满意,因为

  1. 查询项目奖励两次,并在以下步骤中展开它们。这将生成二次多个中间文档;
  2. 查询计算辅助字段" super"这只用于之后的过滤。
  3. 有没有更好的方法来制定此查询?

1 个答案:

答案 0 :(得分:1)

尝试以下聚合管道:

db.bios.aggregate([
    {
        "$unwind": "$awards"
    },
    {
        "$group": {
            "_id": {
                "year": "$awards.year",
                "firstName": "$name.first",
                "lastName": "$name.last"
            },
            "count": { "$sum": 1 },
            "award_recepients": { "$push": "$name" }
        }
    },
    {
        "$match": { "count": 2 }
    },
    {
        "$project": {
            "_id": 0,
            "year": "$_id.year",
            "award_recepients": 1,
            "count": 1
        }
    }
])