Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
来自MongoDB中的值的动态键_Mongodb_Mongodb Query - Fatal编程技术网

来自MongoDB中的值的动态键

来自MongoDB中的值的动态键,mongodb,mongodb-query,Mongodb,Mongodb Query,假设我有这个: { "_id" : "ENVD", "years" : [ { "year" : "2013", "avgInstructor" : 5.144999999999998 }, { "year" : "2012",

假设我有这个:

{
        "_id" : "ENVD",
        "years" : [
                {
                        "year" : "2013",
                        "avgInstructor" : 5.144999999999998
                },
                {
                        "year" : "2012",
                        "avgInstructor" : 5.194436090225564
                }
        ]
}
我需要能够找到2012-13年阿金斯卡车领域的差异。我在想,我可以用一个
$project
来转换这些键,这将使年份成为键,而avgInstructor评级则是值。所以看起来是这样的:

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

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

一个可能的答案

  • 先放松
  • 项目,使其更易于处理
  • 按id排序,然后按年份排序
  • 分组依据_id以拾取第一个和最后一个值
  • 最终投影以获得减去的值

    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" ] }  } }
    
    ] )
    

  • 对于在最近版本的MongoDB中寻找使用聚合将数组转换为对象的解决方案的人:

    引入MongoDB 3.4.4

    您必须

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

    {
    “_id”:“ENVD”,
    “年”:[
    ["2013", 5.144999999999998],
    ["2012", 5.194436090225564]
    ]
    }
    
    然后使用

    或者将这两个步骤结合在一起

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

    我总是感到惊讶,为什么有人会认为这是一件好事,而不是它的存储方式。另外,无论您想在这里做什么,如果您不在文档之间实际聚合任何内容,那么代码中的效率可能会更高。您是否看到我关于提供更好的解决方案(如果您看到的话)的评论?你的评论没有多大帮助。注意:1)这是一个小数据集,因此性能不是最重要的。2) 我被要求只使用一个Mongo查询来完成这个任务。这主要是一种学习经验,我更愿意将其编码出来(这是一个相对简单的问题),我想是的,至少有一个人同意。看来最好的解决办法是保持现状。只需减去:
    years[0]。avgInstructor-years[1]。avgInstructor
    或在
    map()
    之后使用
    indexOf(“2013)
    ,就可以得到元素索引或任何语言等价的符号。您不是在聚合文档,因此这似乎是不必要的工作。
      {
        $set: {
          years: {
            $arrayToObject: {
              $map: {
                input: "$years",
                as: "year",
                in: [
                  "$$year.year",
                  "$$year.avgInstructor"
                ]
              }
            }
          }
        }
      }