change stream 的 update 事件里为什么没有整个文档?updateLookup 拿到的是不是修改后的样子?怎么在服务端过滤?这篇逐个验证事件内容、两种镜像方案和 pipeline 过滤。
{ operationType: 'insert', documentKey: { _id: 2 }, fullDocument: { _id: 2, status: 'new', n: 0 } }
{ operationType: 'update', documentKey: { _id: 2 }, updateDescription: { updatedFields: { status: 'paid' }, removedFields: [ 'n' ], truncatedArrays: [] } }
{ operationType: 'replace', documentKey: { _id: 2 }, fullDocument: { _id: 2, status: 'replaced' } }
{ operationType: 'delete', documentKey: { _id: 2 } }insert / replace 带完整文档,update 只带 updateDescription(updatedFields、removedFields、truncatedArrays),delete 只有 documentKey。
update 事件的 updatedFields={'n': 1};updateLookup 取回的 fullDocument.n = 2
update 事件的 updatedFields={'n': 2};updateLookup 取回的 fullDocument.n = 2
(两个事件的 fullDocument.n 都是 2:第一个事件对应的 n=1 那个中间状态丢了)fullDocument: "updateLookup" 在读取事件时去查当前文档,所以连续修改时看到的是最新状态,不是该次修改后的样子。
update 事件:前镜像 n = 2,后镜像 n = 10 (updatedFields={'n': 10})
update 事件:前镜像 n = 10,后镜像 n = 20 (updatedFields={'n': 20})
delete 事件:operationType=delete,documentKey={'_id': 1};fullDocumentBeforeChange = {'_id': 1, 'status': 'new', 'n': 20, 'tags': [1, 2, 3]}(删除前的完整文档)集合上打开 changeStreamPreAndPostImages 后,required 能拿到精确的前镜像与后镜像,delete 事件也能拿到删除前的文档。
不带过滤的 stream 收到 10 个事件;带 $match 的 stream 收到 4 个,documentKey: [0, 3, 6, 9](i % 3 == 0 的 4 个)
watch 的 pipeline 里 $match 在服务端过滤,只把匹配的事件发给客户端。
收到 2 个事件(只有 vip 的):[{'operationType': 'insert', 'fullDocument': {'kind': 'vip', 'name': 'a'}}, {'operationType': 'insert', 'fullDocument': {'kind': 'vip', 'name': 'c'}}]
去掉 _id 的 $project:OperationFailure: Executor error during getMore :: caused by :: Encountered an event whose _id field, which contains the resume token, was modified 可以裁剪字段减少传输,但不能改动 _id(它就是 resume token)。
drop 之后收到: ['drop', 'invalidate'];stream.alive = False
集合被删除时 stream 依次收到 drop 和 invalidate 然后关闭,需要重新打开。