$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   } ]