$locf(聚合)
定义
语法
$locf表达式具有以下语法
{ $locf: <expression> }
有关表达式更多信息,请参阅表达式运算符。
行为
如果一个字段同时包含null和非空值,则$locf将根据在$setWindowFields中指定的排序顺序,将该字段的null和缺失值设置为该字段最后已知的非空值。
在排序顺序中出现在非空值之前的null和缺失字段值保持为null。
如果一个字段在分区中只包含null或缺失值,则$locf将该分区字段值设置为null。
比较 $fill 和 $locf
要根据序列中的最后一个观测值填充缺失的字段值,可以使用
带有
{ method: "locf" }的$fill阶段。当使用
$fill阶段时,输出中指定的字段与源数据中使用的字段相同。请参阅 根据最后一个观测值填充缺失字段值。在
$setWindowFields阶段内的$locf操作符。当使用
$locf操作符时,可以为不同于源数据字段的不同字段设置值。请参阅 在一个阶段中使用多个填充方法。
示例
此页上的示例使用一个包含单个公司按小时间隔跟踪股价的 stock 集合。
db.stock.insertMany( [ { time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, { time: ISODate("2021-03-08T10:00:00.000Z"), }, { time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, { time: ISODate("2021-03-08T12:00:00.000Z") }, { time: ISODate("2021-03-08T13:00:00.000Z") }, { time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } ] )
集合中的一些文档缺少 price 字段。
用最后观察到的值填充缺失值
以下示例使用$locf运算符将缺失字段设置为最后观察到的非null值
db.stock.aggregate( [ { $setWindowFields: { sortBy: { time: 1 }, output: { price: { $locf: "$price" } } } } ] )
在示例中
示例输出
[ { _id: ObjectId("62169b65394d47411658b5f5"), time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, { _id: ObjectId("62169b65394d47411658b5f6"), time: ISODate("2021-03-08T10:00:00.000Z"), price: 500 }, { _id: ObjectId("62169b65394d47411658b5f7"), time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, { _id: ObjectId("62169b65394d47411658b5f8"), time: ISODate("2021-03-08T12:00:00.000Z"), price: 515 }, { _id: ObjectId("62169b65394d47411658b5f9"), time: ISODate("2021-03-08T13:00:00.000Z"), price: 515 }, { _id: ObjectId("62169b65394d47411658b5fa"), time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 } ]
在单个阶段中使用多种填充方法
当使用$setWindowFields阶段填充缺失值时,可以为不同于填充字段的字段设置值。因此,可以在单个$setWindowFields阶段中使用多种填充方法,并将结果输出到不同的字段。
以下管道使用线性插值和最近观测值前移方法填充缺少的价格字段。
db.stock.aggregate( [ { $setWindowFields: { sortBy: { time: 1 }, output: { linearFillPrice: { $linearFill: "$price" }, locfPrice: { $locf: "$price" } } } } ] )
在示例中
sortBy: { time: 1 }按时间字段以升序对文档进行排序,从最早到最新。输出指定
linearFillPrice作为要填充的目标字段。{ $linearFill: "$price" }是linearFillPrice字段的值。$linearFill根据序列中周围的价格值使用线性插值填充缺少的价格值。
locfPrice作为要填充的目标字段。{ $locf: "$price" }是locfPrice字段的值。locf代表最近观测值前移。$locf使用序列中前一个文档的值填充缺少的价格值。
示例输出
[ { _id: ObjectId("620ad555394d47411658b5ef"), time: ISODate("2021-03-08T09:00:00.000Z"), price: 500, linearFillPrice: 500, locfPrice: 500 }, { _id: ObjectId("620ad555394d47411658b5f0"), time: ISODate("2021-03-08T10:00:00.000Z"), linearFillPrice: 507.5, locfPrice: 500 }, { _id: ObjectId("620ad555394d47411658b5f1"), time: ISODate("2021-03-08T11:00:00.000Z"), price: 515, linearFillPrice: 515, locfPrice: 515 }, { _id: ObjectId("620ad555394d47411658b5f2"), time: ISODate("2021-03-08T12:00:00.000Z"), linearFillPrice: 505, locfPrice: 515 }, { _id: ObjectId("620ad555394d47411658b5f3"), time: ISODate("2021-03-08T13:00:00.000Z"), linearFillPrice: 495, locfPrice: 515 }, { _id: ObjectId("620ad555394d47411658b5f4"), time: ISODate("2021-03-08T14:00:00.000Z"), price: 485, linearFillPrice: 485, locfPrice: 485 } ]