来自MongoDB中值的动态键

时间:2015-01-19 20:31:08

标签: mongodb mongodb-query

说我有这个:

{
        "_id" : "ENVD",
        "years" : [
                {
                        "year" : "2013",
                        "avgInstructor" : 5.144999999999998
                },
                {
                        "year" : "2012",
                        "avgInstructor" : 5.194436090225564
                }
        ]
}

我需要能够在2012-13中找到avgInstructor字段的差异。我以为我可以使用$project以某种方式转换密钥,这将使年份成为关键,而avgInstructor评级为值。所以它看起来像这样:

{
        "_id" : "ENVD",
        "years" : {
                        "2013" : 5.144999999999998,
                        "2012" : 5.194436090225564
         }

}

这可能吗?请记住,我的主要目标是能够像这个伪代码一样运行减法:years['2013'].avgInstructor - years['2013'].avgInstructor。所以如果你看到一个更简单的方法,那也会很棒。我不确定在聚合管道的上下文中最好的方法。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

对于最终来到这里的人们,他们正在寻找一种解决方案,以便在最新版本的MongoDB中使用聚合将数组转换为对象:

MongoDB 3.4.4引入了$arrayToObject

您必须$map years

  {
    $set: {
      years: {
        $map: {
          input: "$years",
          as: "year",
          in: [
            "$$year.year",
            "$$year.avgInstructor"
          ]
        }
      }
    }
  }

要这样

{
  "_id" : "ENVD",
  "years": [
    ["2013", 5.144999999999998],
    ["2012", 5.194436090225564]
  ]
}

然后使用$arrayToObject

  {
    $set: {
      years: {
        $arrayToObject: "$years"
      }
    }
  }

或将两个步骤结合在一起

  {
    $set: {
      years: {
        $arrayToObject: {
          $map: {
            input: "$years",
            as: "year",
            in: [
              "$$year.year",
              "$$year.avgInstructor"
            ]
          }
        }
      }
    }
  }

答案 1 :(得分:0)

可能的答案......

  1. 先放松
  2. 项目使其更容易处理
  3. 按_id然后按年排序
  4. 按_id分组以获取第一个和最后一个值
  5. 获得减去值的最终投影

    db.coll.aggregate ( [
    
            { "$unwind" : "$years"  } ,
    
            { $project : { "year" : "$years.year", "avgInstructor" : "$years.avgInstructor"  } },
    
            { $sort : { "_id" : 1, "year" : 1 } },
    
            { $group : { "_id" : "$_id", "val_min" : { $first : "$avgInstructor"  },  "val_max" : { $last : "$avgInstructor" } } },
    
            { $project : { "diff" : { $subtract : [ "$val_min", "$val_max" ] }  } }
    
    ] )