MongoDB聚合运算符:$tsIncrement
文章目录
- [MongoDB聚合运算符:tsIncrement](#MongoDB聚合运算符:tsIncrement)
-
- 语法
- 使用
- 举例
-
- 从时间戳字段获取递增序数
- [在变化的数据流游标中使用 $tsIncrement 来监控集合变化](#在变化的数据流游标中使用 $tsIncrement 来监控集合变化)
$tsIncrement
用来以 long
形式返回时间戳的递增序数。当同一秒内发生多个事件时,递增序数唯一标识每个事件。
语法
js
{ $tsIncrement: <expression> }
<expression>
表达式必须能解析为时间戳。
使用
- 如果输入表达式的值为
null
或引用的字段缺失,则$tsIncrement
返回null
。 - 如果输入表达式的值不是时间戳,则返回错误。
举例
从时间戳字段获取递增序数
使用下面的脚本创建stockSales
集合,包含公司股票金融市场销售的情况:
js
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) }
] )
下面的聚合操作使用$tsIncrement
表达式计算角度angle
的双曲正切值,然后使用$addFields
管道阶段将其添加到输入文档。
js
db.trigonometry.aggregate( [
{
$addFields : {
"tanh_output" : { $tsIncrement : { $degreesToRadians : "$angle" } }
}
}
] )
在时间戳构造函数中:
- 第一个值是 Unix 纪元之后的秒数。
- 第二个值是递增序号。当同一秒内发生多个事件时,递增序号将唯一标识每个事件。
下面的示例在 $project
阶段使用 $tsIncrement
从股票销售 salesTimestamp
字段返回递增序号:
js
db.stockSales.aggregate( [
{
$project:
{
_id: 0, saleTimestamp: 1, saleIncrement: { $tsIncrement: "$saleTimestamp" }
}
}
] )
在示例中,$project 只包括 saleTimestamp 和 saleIncrement 字段,如下输出所示:
js
{
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")
}
在变化的数据流游标中使用 $tsIncrement 来监控集合变化
下面的示例在变化数据流游标中使用了$tsIncrement
,返回在同一秒钟内对集合所做的每一次更改。
在cakeSales
集合上创建一个变化流游标:
js
cakeSalesCursor = db.cakeSales.watch( [
{
$match: {
$expr: {
$eq: [
{ $mod: [ { $tsIncrement: "$clusterTime" } , 2 ] },
0
]
}
}
}
] )
在本例中:
db.collection.watch()
方法为cakeSales
集合创建一个变化流游标,并将该游标存储在cakeSalesCursor
中。$match
阶段使用$expr
运算符对文档进行过滤。- $expr 运算符:
- 将
$mod 2
应用于由$tsIncrement
返回的$clusterTime
变量的递增序号。 $clusterTime
为修改cakeSales
集合时来自oplog
条目的时间戳。- 使用
$eq
对$mod
返回值与0
比较。
- 将
创建一个cakeSales
集合,其中包含加利福尼亚州 (CA) 和华盛顿州 (WA) 的蛋糕销售情况:
js
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 }
] )
可以使用cakeSalesCursor
来监视cakeSales
集合的更改,例如,使用 next()方法获取cakeSalesCursor
的下一个文档:
js
cakeSalesCursor.next()
根据文档添加到cakeSales
的秒数不同,cakeSalesCursor.next()
的输出也不同,例如,文档添加时间可能超过一秒。
下面的cakeSalesCursor.next()
输出示例显示了添加到 cakeSales
集合的第一个文档的插入详细信息。注意,在 clusterTime
字段中,递增序号 i
为 2
。
js
_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()
,返回clusterTime
递增序号 i
为 4
的 cakeSales
文档,忽略 i
为 3
的文档。