从 MongoDB 版本 7.0 开始,您可以使用 $out 聚合阶段将现有集合中的数据迁移到时间序列集合中。
注意
当您使用 $out 将数据迁移到时间序列集合时,MongoDB 不保证输出顺序。为了保持数据的顺序,请先对数据进行排序,再使用聚合管道进行迁移。
开始之前
考虑一个包含时间和元数据信息的 weatherdata 集合:
db.weatherdata.insertOne( { _id: ObjectId("5553a998e4b02cf7151190b8"), st: "x+47600-047900", ts: ISODate("1984-03-05T13:00:00Z"), position: { type: "Point", coordinates: [ -47.9, 47.6 ] }, elevation: 9999, callLetters: "VCSZ", qualityControlProcess: "V020", dataSource: "4", type: "FM-13", airTemperature: { value: -3.1, quality: "1" }, dewPoint: { value: 999.9, quality : "9" }, pressure: { value: 1015.3, quality: "1" }, wind: { direction: { angle: 999, quality: "9" }, type: "9", speed: { rate: 999.9, quality: "9" } }, visibility: { distance: { value: 999999, quality : "9" }, variability: { value: "N", quality: "9" } }, skyCondition: { ceilingHeight: { value: 99999, quality: "9", determination: "9" }, cavok: "N" }, sections: [ "AG1" ], precipitationEstimatedObservation: { discrepancy: "2", estimatedWaterDepth: 999 } } )
步骤
创建元数据字段。
如果您的集合不包含可用于标识每个系列的字段,请转换数据以定义一个。在此示例中,metaData 字段成为您创建的时间序列集合的 metaField。
注意
选择正确的字段作为时间序列 metaField 和 grandularity 可优化存储和查询性能。有关字段选择和最佳实践的更多信息,请参阅 metaField 和粒度最佳实践。
以下管道执行以下操作:
使用
$addFields将metaData字段添加到weather_data集合。使用
$project包含或排除文档中的其余字段。
db.weather_data.aggregate([ { $addFields: { metaData: { "st": "$st", "position": "$position", "elevation": "$elevation", "callLetters": "$callLetters", "qualityControlProcess": "$qualityControlProcess", "type": "$type" } }, }, { $project: { _id: 1, ts: 1, metaData: 1, dataSource: 1, airTemperature: 1, dewPoint: 1, pressure: 1, wind: 1, visibility: 1, skyCondition: 1, sections: 1, precipitationEstimatedObservation: 1 } } ])
创建您的时间序列集合并插入数据。
在管道中添加一个 $out 聚合阶段,以创建时间序列集合并将数据插入其中。以下管道执行以下操作:
使用带有
timeseries选项的$out在mydatabase数据库中创建weathernew时间序列集合。将
metaData字段定义为weathernew集合的metaField。将
ts字段定义为weathernew集合的timeField。注意
时间序列集合的
timeField必须是日期类型。
{ $out: { db: "mydatabase", coll: "weathernew", timeseries: { timeField: "ts", metaField: "metaData", granularity: "seconds" } } }
请查看您的数据。
运行此聚合管道后,您可以使用 findOne() 查看 weathernew 时间序列集合中的文档:
db.weathernew.findOne()
该操作将返回以下文档:
{ _id: ObjectId("5553a998e4b02cf7151190b8"), ts: ISODate("1984-03-05T13:00:00Z"), metaData: { st: "x+47600-047900", position: { type: "Point", coordinates: [ -47.9, 47.6 ] }, elevation: 9999, callLetters: "VCSZ", qualityControlProcess: "V020", type: "FM-13" }, dataSource: "4", airTemperature: { value: -3.1, quality: "1" }, dewPoint: { value: 999.9, quality: "9" }, pressure: { value: 1015.3, quality: "1" }, wind: { direction: { angle: 999, quality: "9" }, type: "9", speed: { rate: 999.9, quality: "9" } }, visibility: { distance: { value: 999999, quality: "9" }, variability: { value: "N", quality: "9" } }, skyCondition: { ceilingHeight: { value: 99999, quality: "9", determination: "9" }, cavok: "N" }, sections: [ "AG1" ], precipitationEstimatedObservation: { discrepancy: "2", estimatedWaterDepth: 999 } }
后续步骤
如果原始集合中有二级索引,请现在手动重新创建。
如果时间序列集合在 1970-01-01T00:00:00.000Z 之前或 2038-01-19T03:14:07.000Z 之后包含 timeField 个值,MongoDB 会记录警告并禁用某些使用内部聚集索引的查询优化。要恢复查询性能并解决日志警告问题,请在 timeField 上创建二级索引。