MongoDB聚合:$densify

$densify阶段可以为文档序列中字段缺失的某些值创建新文档。其主要的用途有:

  • 补齐时间序列数据。
  • 为分组数据添加缺失值。
  • 为指定的值范围填充数据。

语法

$densify阶段的语法:

{
   
   
   $densify: {
   
   
      field: <fieldName>,
      partitionByFields: [ <field 1>, <field 2> ... <field n> ],
      range: {
   
   
         step: <number>,
         unit: <time unit>,
         bounds: < "full" || "partition" > || [ < lower bound >, < upper bound > ]
      }
   }
}

$densify阶段的参数主要有以下字段:

field

必选字段,要填充的字段,字段的值必须是数值或日期类型,文档中其他没有被field指定的字段则会直接通过管道,不会被修改。如果指定的<field>在内嵌文档或数组中,需要使用点号。

partitionByFields

可选字段,一组字段构成的键值用于对文档进行分组。在$densify阶段,每组文档被称为一个分区。若省略这个字段,$densify则对整个集合使用一个分组。

range

必选字段,一个对象,指定数据如何被填充。

range.bounds

必选字段,可以用下面两种方式指定range.bounds

  • 数组形式:[ < lower bound >, < upper bound > ],
  • 字符串形式:"full""partition"

如果bounds是一个数组:

  • $densify添加涵盖指定范围值的文档。
  • bounds的数据类型必须与填充的字段类型保持一致。

如果bounds"full"

  • $densify添加涵盖指定范围值的文档。

如果bounds"partition"

  • $densify将文档添加到每个分区,类似于单独对每个分区单独运行full范围致密化。

range.step

必须字段,所有文档中field值的增量,$densify按照step(步长)在已经存在的文档之间创建新文档。如果指定了range.unit字段,step必须是一个整数,否则step可以是任意的数值。

range.unit

如果field为日期则是必须字段,unit用于日期类型的field增量的单位。可以指定为下面字符串的值之一:

  • millisecond
  • second
  • minute
  • hour
  • day
  • week
  • month
  • quarter
  • year

使用

field的限制

如果文档包含的field有下列情况将报错:

  • 集合中任何文档中指定的field值有日期类型,且没有指定unit字段的
  • 集合中任何文档中指定的field值有数值类型,且没有指定unit字段的
  • 如果要densify的字段field名称以$开头,必须要对其改名,可以使用$project

partitionByFields的限制

下面的情况出现在partitionByFields数组字段名中时将报错:

  • 求值结果为非字符串值
  • $开头

range.bounds的行为

如果range.bounds是一个数组:

  • 下限值表示新增文档的起始值,与集合中已有的文档无关。
  • 下限包含在内。
  • 上限不包含在内。
  • $densify不会过滤掉字段值超出指定范围的文档。

输出顺序

$densify不保证输出文档的顺序。想要保证有序,可以使用$sort对想要排序的字段进行排序。

举例

填充时间序列数据

创建一个包含四小时温度读数的weather集合。

db.weather.insertMany( [
   {
   
   
       "metadata": {
   
    "sensorId": 5578, "type": "temperature" },
       "timestamp": ISODate("2021-05-18T00:00:00.000Z"),
       "temp": 12
   },
   {
   
   
       "metadata": {
   
    "sensorId": 5578, "type": "temperature" },
       "timestamp": ISODate("2021-05-18T04:00:00.000Z"),
       "temp": 11
   },
   {
   
   
       "metadata": {
   
    "sensorId": 5578, "type": "temperature" },
       "timestamp": ISODate("2021-05-18T08:00:00.000Z"),
       "temp": 11
   },
   {
   
   
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

原子星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值