首页 > 解决方案 > 重组文件:这可能吗?

问题描述

假设我有一个看起来像这样的集合:

{
   "_id":  ObjectId(...),
   "recorded": ISODate("2018-05-05T11:05:32.000"),
   "devices": [
       {
           "id": "KSA2",
           "temp": 32,
           "ttl": 10
       },
       {
           "id": "KSA24",
           "temp": 28,
           "ttl": 10
       }       
   ]  
}
{
   "_id":  ObjectId(...),
   "recorded": ISODate("2018-05-05T18:23:45.000"),
   "devices": [
       {
           "id": "KSA2",
           "temp": 31,
           "ttl": 10
       },
       {
           "id": "KSA24",
           "temp": 16,
           "ttl": 10
       }       
   ]  
}

我需要做的是通过设备将其转换为文档:

{
    "Devices": [
        {
            "id": "KSA2",
            "observations": [
                {
                    "time":ISODate("2018-05-05T11:05:32.000"),
                    "temp":32,
                    "ttl":10
                }
                {
                    "time":ISODate("2018-05-05T18:23:45.000"),
                    "temp":31,
                    "ttl":10
                }
            ]


        },
        {
            "id":"KSA24",
            ...
        }
    ]
}

这是否可以使用聚合框架在“内部”mongodb 中执行,或者我是否需要在外部使用 Python 或类似的东西执行此操作?

标签: mongodb

解决方案


在您的集合上运行以下聚合:

db['myCollection'].aggregate(
    [
        {
            $unwind: {
                path : "$devices",

            }
        },
        {
            $group: {
            _id : "$devices.id",
            observations : {$push : 
              {
                time : "$recorded",
                temp:"$devices.temp",
                ttl:"$devices.ttl"}
              }
            }
        },
        {
            $out: "devices"
        },
    ],
);

使用阶段:

  • $unwind:为每个设备元素创建一个文档。
  • $group:按设备 id 分组,将自定义子文档推送到 bservation 数组。
  • $out:将结果输出到一个新的集合,这里是“设备”。

这将在设备集合中输出:

db['devices'].find();
{ 
    "_id" : "KSA24", 
    "observations" : [
        {
            "time" : ISODate("2018-05-05T13:05:32.000+0200"), 
            "temp" : 28.0, 
            "ttl" : 10.0
        }, 
        {
            "time" : ISODate("2018-05-05T20:23:45.000+0200"), 
            "temp" : 16.0, 
            "ttl" : 10.0
        }
    ]
}
{ 
    "_id" : "KSA2", 
    "observations" : [
        {
            "time" : ISODate("2018-05-05T13:05:32.000+0200"), 
            "temp" : 32.0, 
            "ttl" : 10.0
        }, 
        {
            "time" : ISODate("2018-05-05T20:23:45.000+0200"), 
            "temp" : 31.0, 
            "ttl" : 10.0
        }
    ]
}

之后,使用新设备集合,或将其重命名为您的旧名称。


推荐阅读