【问题标题】:MongoDB 'unwind' nested objectsMongoDB“展开”嵌套对象
【发布时间】:2016-09-23 10:28:23
【问题描述】:

我有一个集合,其中每个文档看起来像这样:

{
_id: 'dev_id:datetime_hour',
data: {
    0: { 
        0: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        },
        1: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        },
        2: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        },
        59: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        } 
    },
    1: { 
        0: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        },
        1: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        },
        2: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        },
        59: {
            voltage_a: float, 
            voltage_b: float, 
            voltage_c: float, 
            current_a: float, 
            current_b: float, 
            current_c: float, 
            current_n: float, 
            active_power_a: float, 
            active_power_b: float, 
            active_power_c: float, 
            total_active_power: float   
        } 
    }
}

我在这里对其进行了简化,但基本思想是:传感器数据每秒存储一次,但按小时捆绑在一起。 “数据”字段按分钟索引这些,每分钟按秒索引。因此,一个完整小时的数据将在嵌套数据字段中产生 3600 个条目。例如,要获取第一分钟和第三秒的传感器数据,我可以直接访问对象:data.1.3

这种类型的架构是recommended for storing time series data by MongoDB

我的聚合管道的第 1 阶段如下所示:

db.raw_electric.aggregate(
  [
    // Stage 1
    {
      $match: {
        _id: { $regex: /^r10a:/ },
        datehour: {$gte: ISODate("2016-09-21T17:00:00"), $lte: ISODate("2016-09-21T19:00:00")}
      }
    }

  ]

);

是否可以“展开”文档 - 类似于展开数组以便我可以公开对象的每个嵌套层的方式?

【问题讨论】:

  • 您不能使用 $unwind 运算符“展开”文档,它仅适用于数组。
  • 我知道...这就是为什么我正在为这种情况寻找等效/替代方案。

标签: mongodb


【解决方案1】:

您应该通过以下方式创建架构:

{
    _id: 'dev_id:datetime_hour',
    data: [{
        name: '0',
        info: [{}]
    }]
}

即您的数据应该是一个对象数组。您可以从该数组中使用其索引获取任何对象。

{
    _id: 'dev_id:datetime_hour',
    data: [{
            name: '0',
            info: [{
                voltage_a: float,
                voltage_b: float,
                voltage_c: float,
                current_a: float,
                current_b: float,
                current_c: float,
                current_n: float,
                active_power_a: float,
                active_power_b: float,
                active_power_c: float,
                total_active_power: float
            }, {
                voltage_a: float,
                voltage_b: float,
                voltage_c: float,
                current_a: float,
                current_b: float,
                current_c: float,
                current_n: float,
                active_power_a: float,
                active_power_b: float,
                active_power_c: float,
                total_active_power: float
            }, {
                voltage_a: float,
                voltage_b: float,
                voltage_c: float,
                current_a: float,
                current_b: float,
                current_c: float,
                current_n: float,
                active_power_a: float,
                active_power_b: float,
                active_power_c: float,
                total_active_power: float
            }, {
                voltage_a: float,
                voltage_b: float,
                voltage_c: float,
                current_a: float,
                current_b: float,
                current_c: float,
                current_n: float,
                active_power_a: float,
                active_power_b: float,
                active_power_c: float,
                total_active_power: float
            }],
            {
                name: '1',
                info: [{
                        voltage_a: float,
                        voltage_b: float,
                        voltage_c: float,
                        current_a: float,
                        current_b: float,
                        current_c: float,
                        current_n: float,
                        active_power_a: float,
                        active_power_b: float,
                        active_power_c: float,
                        total_active_power: float
                    }, {
                        voltage_a: float,
                        voltage_b: float,
                        voltage_c: float,
                        current_a: float,
                        current_b: float,
                        current_c: float,
                        current_n: float,
                        active_power_a: float,
                        active_power_b: float,
                        active_power_c: float,
                        total_active_power: float
                    }
                }]
        }
    }]
}

【讨论】:

  • @AbdulMaye。很高兴听到它有帮助。如果它工作正常,请不要忘记标记答案。干杯。
  • 看来这可能会简化查询过程,但我将如何实际更新这些记录?假设我想为具有name:1 的对象附加信息数组。我正在使用updateOneupsert: true
  • 使用此查询更新或推送信息数组中的对象:db.getCollection('test').update({"_id" : ObjectId("57e89f3c6be4d87da7824d28"),"data.name" :"0"}, {$addToSet:{'data.$.info':{v1:'v1',v2:'v2'}}})
  • 好的,所以似乎没有简单的方法可以做我想做的事。我已经尝试并使用位置运算符 $ 意味着我不能做 upserts,因为当我尝试这样做时我的 mongo 驱动程序会抛出一个错误,并且它一开始就找不到匹配项......我想我会有随着架构的变化 - 更扁平的结构......
【解决方案2】:

似乎您有多个嵌套对象。在您的情况下,如果您考虑将展开以获得 1 小时数据的总数组,它将是:1*60*60 = 3600。

此外,多重嵌套不必要地增加了检索和更新数据的复杂性。

你需要一个更扁平的结构,可以如下实现:-

为每分钟创建单独的文档。结构类似于 -

{
 _id: ObjectId('');
 hour: 1,
 minute: 1
 seconds: [
  {
   item: 0,
   voltage_a: float,
   voltage_b: float,
   voltage_c: float,
   current_a: float,
   current_b: float,
   current_c: float,
   current_n: float,
   active_power_a: float,
   active_power_b: float,
   active_power_c: float,
   total_active_power: float
  },
  {
   item: 1,
   voltage_a: float,
   voltage_b: float,
   voltage_c: float,
   current_a: float,
   current_b: float,
   current_c: float,
   current_n: float,
   active_power_a: float,
   active_power_b: float,
   active_power_c: float,
   total_active_power: float
  }
 ]
},
{
 _id: ObjectId('');
 hour: 1,
 minute: 2
 seconds: [
  {
   item: 0,
   voltage_a: float,
   voltage_b: float,
   voltage_c: float,
   current_a: float,
   current_b: float,
   current_c: float,
   current_n: float,
   active_power_a: float,
   active_power_b: float,
   active_power_c: float,
   total_active_power: float
  },
  {
   item: 1,
   voltage_a: float,
   voltage_b: float,
   voltage_c: float,
   current_a: float,
   current_b: float,
   current_c: float,
   current_n: float,
   active_power_a: float,
   active_power_b: float,
   active_power_c: float,
   total_active_power: float
  }
 ]
}

这种结构随后可能会增加文档的数量。但会降低查询所涉及的复杂性。此外,通过有效的索引,可以保持性能。 (对于大数据,您还应该考虑分片)。

【讨论】:

    猜你喜欢
    • 2018-11-04
    • 2021-07-20
    • 2019-01-19
    • 2016-04-19
    • 2016-06-25
    • 2018-10-24
    • 2019-07-28
    • 2021-01-24
    • 1970-01-01
    相关资源
    最近更新 更多