$tsIncrement (聚合)
定义
新增在版本5.1.
当同一秒内发生多个事件时,递增序号唯一标识每个事件。
$tsIncrement
语法
{ $tsIncrement: <expression> }
表达式必须解析为时间戳。
行为
$tsIncrement
返回
Null
如果输入表达式评估为null
或引用了缺失的字段。如果输入表达式没有评估为 时间戳,则引发错误。
示例
从时间戳字段获取递增序号
创建一个包含公司股票金融市场销售的 stockSales
集合
db.stockSales.insertMany( [ { _id: 0, symbol: "MDB", saleTimestamp: Timestamp(1622731060, 1) }, { _id: 1, symbol: "MDB", saleTimestamp: Timestamp(1622731060, 2) }, { _id: 2, symbol: "MSFT", saleTimestamp: Timestamp(1714124193, 1) }, { _id: 3, symbol: "MSFT", saleTimestamp: Timestamp(1714124193, 2) }, { _id: 4, symbol: "MSFT", saleTimestamp: Timestamp(1714124193, 3) } ] )
在 时间戳 构造函数中,
第一个值是自 Unix 纪元以来的秒数。
第二个值是递增序号。当同一秒内发生多个事件时,递增序号可以唯一标识每个事件。
以下示例使用 $tsIncrement
在 $project
阶段中,从股票销售的 saleTimestamp
字段返回递增序号
db.stockSales.aggregate( [ { $project: { _id: 0, saleTimestamp: 1, saleIncrement: { $tsIncrement: "$saleTimestamp" } } } ] )
在示例中,$project
只包括 saleTimestamp
和 saleIncrement
字段,如下所示
{ saleTimestamp: Timestamp({ t: 1622731060, i: 1 }), saleIncrement: Long("1") }, { saleTimestamp: Timestamp({ t: 1622731060, i: 2 }), saleIncrement: Long("2") }, { saleTimestamp: Timestamp({ t: 1714124193, i: 1 }), saleIncrement: Long("1") }, { saleTimestamp: Timestamp({ t: 1714124193, i: 2 }), saleIncrement: Long("2") }, { saleTimestamp: Timestamp({ t: 1714124193, i: 3 }), saleIncrement: Long("3") }
在 Change Stream Cursor 中使用 $tsIncrement
来监控集合变化
本节中的示例使用 $tsIncrement
在 change stream cursor 中,以返回同一秒内对集合所做的每个其他更改。
创建一个名为 cakeSales
的集合的 change stream cursor,您将在本节后面看到它
cakeSalesCursor = db.cakeSales.watch( [ { $match: { $expr: { $eq: [ { $mod: [ { $tsIncrement: "$clusterTime" } , 2 ] }, 0 ] } } } ] )
在示例中,
db.collection.watch()
方法为cakeSales
集合创建了一个 change stream cursor,并将其存储在cakeSalesCursor
中。$expr
操作符
创建一个包含加利福尼亚州(CA
)和华盛顿州(WA
)的糕点销售的 cakeSales
集合
db.cakeSales.insertMany( [ { _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"), state: "CA", price: 13, quantity: 120 }, { _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"), state: "WA", price: 14, quantity: 140 }, { _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"), state: "CA", price: 12, quantity: 145 }, { _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"), state: "WA", price: 13, quantity: 104 }, { _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"), state: "CA", price: 41, quantity: 162 }, { _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"), state: "WA", price: 43, quantity: 134 } ] )
要监控 cakeSales
集合的变化,请使用 cakeSalesCursor
。例如,要从 cakeSalesCursor
获取下一个文档,请使用 next()
方法
cakeSalesCursor.next()
根据文档添加到 cakeSales
的时间,cakeSalesCursor.next()
的输出会有所不同。例如,文档添加可能跨越超过一秒的时间。
以下 cakeSalesCursor.next()
示例输出显示了添加到 cakeSales
集合的第一个文档的 insert
详细信息。注意在 clusterTime
字段中,递增的序号 i
为 2
。
_id: { _data: '82613A4F25000000022B022C0100296E5A100454C5BFAF538C47AB950614F43889BE00461E5F696400290004' }, operationType: 'insert', clusterTime: Timestamp({ t: 1631211301, i: 2 }), fullDocument: { _id: 0, type: 'chocolate', orderDate: ISODate("2020-05-18T14:10:30.000Z"), state: 'CA', price: 13, quantity: 120 }, ns: { db: 'test', coll: 'cakeSales' }, documentKey: { _id: 0 }
再次运行 cakeSalesCursor.next()
将返回 cakeSales
文档,其中 clusterTime
的递增序号 i
为 4
,跳过了 i
为 3
的文档。