文档菜单
文档首页
/
MongoDB 手册
/ / /

$densify (聚合)

本页

  • 定义
  • 语法
  • 行为和限制
  • 示例
$densify

版本5.1.

在文档序列中创建新文档,其中某个字段的某些值缺失。

您可以使用$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>,使用点表示法.

有关限制,请参阅 field Restrictions.

可选

作为组合键以分组文档的字段集合。在 $densify 阶段中,每个文档组被称为一个 partition

如果您省略此字段,$densify 将使用一个分区处理整个集合。

有关示例,请参阅 Densifiction with Partitions.

有关限制,请参阅 partitionByFields Restrictions.

必填

指定数据如何加密的对象。

必填

您可以指定 range.bounds 为以下两种方式之一

  • 数组:[ < lower bound >, < upper bound > ],

  • 字符串:要么是 "full",要么是 "partition"

如果 bounds 是数组

  • $densify 将添加跨越指定范围内的值的文档。

  • 界限的数据类型必须与正在加密的 field 中的数据类型相对应。

  • 有关行为细节,请参阅 range.bounds Behavior.

如果 bounds"full"

  • $densify 将添加跨越正在加密的 field 的完整值范围的文档。

如果 bounds"partition"

  • $densify 将文档添加到每个分区中,类似于在各个分区上分别运行了 full 范围密集化操作。

必填

在每份文档中增加 field 值的数量。 $densify 在现有文档之间的每个 step 创建一个新的文档。

如果指定了 range.unit,则 step 必须是整数。否则,step 可以是任何数值。

如果 field 是日期,则为必填。

当在 field 中增加日期值时,应用到 step 字段的单位。

您可以为 unit 指定以下值之一,作为字符串

  • 毫秒

  • 分钟

  • 小时

  • 季度

有关示例,请参阅 密集化时间序列数据。

对于包含指定 field 的文档,如果以下条件之一不满足,$densify 将出错:

  • 集合中的任何文档都具有日期类型的 字段 值,并且未指定 单位 字段。

  • 集合中的任何文档都具有数值类型的 字段 值,并且已指定 单位 字段。

  • 字段 名称以 $ 开头。如果您想进行密集化处理,必须重命名该字段。要重命名字段,请使用 $project

$densify 如果 partitionByFields 数组中的任何字段名称出错

  • 计算结果不是字符串值。

  • $ 开头。

如果 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
},
{
"metadata": { "sensorId": 5578, "type": "temperature" },
"timestamp": ISODate("2021-05-18T12:00:00.000Z"),
"temp": 12
}
] )

此示例使用 $densify 阶段来填补四个小时间隔之间的空白,以实现数据点的每小时粒度。

db.weather.aggregate( [
{
$densify: {
field: "timestamp",
range: {
step: 1,
unit: "hour",
bounds:[ ISODate("2021-05-18T00:00:00.000Z"), ISODate("2021-05-18T08:00:00.000Z") ]
}
}
}
] )

在示例中

  • $densify 阶段填补了记录温度之间的时间空白。

    • field: "timestamp" 密集化 timestamp 字段。

    • range

      • step: 1timestamp 字段增加 1 单位。

      • 单位:小时通过小时对时间戳字段进行密集化。

      • 范围:[ ISODate("2021-05-18T00:00:00.000Z"), ISODate("2021-05-18T08:00:00.000Z") ]设置了密集化的时间范围。

在以下输出中,$densify阶段填充了00:00:0008:00:00之间的小时时间间隔。

[
{
_id: ObjectId("618c207c63056cfad0ca4309"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T00:00:00.000Z"),
temp: 12
},
{ timestamp: ISODate("2021-05-18T01:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T02:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T03:00:00.000Z") },
{
_id: ObjectId("618c207c63056cfad0ca430a"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T04:00:00.000Z"),
temp: 11
},
{ timestamp: ISODate("2021-05-18T05:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T06:00:00.000Z") },
{ timestamp: ISODate("2021-05-18T07:00:00.000Z") },
{
_id: ObjectId("618c207c63056cfad0ca430b"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T08:00:00.000Z"),
temp: 11
}
{
_id: ObjectId("618c207c63056cfad0ca430c"),
metadata: { sensorId: 5578, type: 'temperature' },
timestamp: ISODate("2021-05-18T12:00:00.000Z"),
temp: 12
}
]

创建一个包含两种咖啡豆数据的coffee集合

db.coffee.insertMany( [
{
"altitude": 600,
"variety": "Arabica Typica",
"score": 68.3
},
{
"altitude": 750,
"variety": "Arabica Typica",
"score": 69.5
},
{
"altitude": 950,
"variety": "Arabica Typica",
"score": 70.5
},
{
"altitude": 1250,
"variety": "Gesha",
"score": 88.15
},
{
"altitude": 1700,
"variety": "Gesha",
"score": 95.5,
"price": 1029
}
] )

此示例使用$densify来密集化每个咖啡品种海拔字段

db.coffee.aggregate( [
{
$densify: {
field: "altitude",
partitionByFields: [ "variety" ],
range: {
bounds: "full",
step: 200
}
}
}
] )

示例聚合

  • 品种分区文档,为阿拉比卡TypicaGesha咖啡创建一个分组。

  • 指定一个范围,意味着数据将密集化到每个分区中现有文档的全范围内。

  • 指定一个步长200,意味着在海拔间隔为200的地方创建新文档。

聚合输出以下文档

[
{
_id: ObjectId("618c031814fbe03334480475"),
altitude: 600,
variety: 'Arabica Typica',
score: 68.3
},
{
_id: ObjectId("618c031814fbe03334480476"),
altitude: 750,
variety: 'Arabica Typica',
score: 69.5
},
{ variety: 'Arabica Typica', altitude: 800 },
{
_id: ObjectId("618c031814fbe03334480477"),
altitude: 950,
variety: 'Arabica Typica',
score: 70.5
},
{ variety: 'Gesha', altitude: 600 },
{ variety: 'Gesha', altitude: 800 },
{ variety: 'Gesha', altitude: 1000 },
{ variety: 'Gesha', altitude: 1200 },
{
_id: ObjectId("618c031814fbe03334480478"),
altitude: 1250,
variety: 'Gesha',
score: 88.15
},
{ variety: 'Gesha', altitude: 1400 },
{ variety: 'Gesha', altitude: 1600 },
{
_id: ObjectId("618c031814fbe03334480479"),
altitude: 1700,
variety: 'Gesha',
score: 95.5,
price: 1029
},
{ variety: 'Arabica Typica', altitude: 1000 },
{ variety: 'Arabica Typica', altitude: 1200 },
{ variety: 'Arabica Typica', altitude: 1400 },
{ variety: 'Arabica Typica', altitude: 1600 }
]

此图像展示了使用$densify创建的文档

State of the coffee collection after full-range densifiction
点击放大
  • 较暗的方块代表集合中的原始文档。

  • 较亮的方块代表使用$densify创建的文档。

此示例使用 $densify 来仅加密每个 variety 中的 altitude 字段的间隔。

db.coffee.aggregate( [
{
$densify: {
field: "altitude",
partitionByFields: [ "variety" ],
range: {
bounds: "partition",
step: 200
}
}
}
] )

示例聚合

  • 品种分区文档,为阿拉比卡TypicaGesha咖啡创建一个分组。

  • 指定一个 partition 范围,意味着数据在每个分区内加密。

    • 对于 Arabica Typica 分区,范围是 600-950

    • 对于 Gesha 分区,范围是 1250-1700

  • 指定一个步长200,意味着在海拔间隔为200的地方创建新文档。

聚合输出以下文档

[
{
_id: ObjectId("618c031814fbe03334480475"),
altitude: 600,
variety: 'Arabica Typica',
score: 68.3
},
{
_id: ObjectId("618c031814fbe03334480476"),
altitude: 750,
variety: 'Arabica Typica',
score: 69.5
},
{ variety: 'Arabica Typica', altitude: 800 },
{
_id: ObjectId("618c031814fbe03334480477"),
altitude: 950,
variety: 'Arabica Typica',
score: 70.5
},
{
_id: ObjectId("618c031814fbe03334480478"),
altitude: 1250,
variety: 'Gesha',
score: 88.15
},
{ variety: 'Gesha', altitude: 1450 },
{ variety: 'Gesha', altitude: 1650 },
{
_id: ObjectId("618c031814fbe03334480479"),
altitude: 1700,
variety: 'Gesha',
score: 95.5,
price: 1029
}
]

此图像展示了使用$densify创建的文档

State of the coffee collection after partition range densification
点击放大
  • 较暗的方块代表集合中的原始文档。

  • 较亮的方块代表使用$densify创建的文档。

返回

$currentOp