ChangeStreams原生支持insert、update、delete、replace四类文档操作,以及drop、rename、dropDatabase等DDL事件(需启用showExpandedEvents:true);不监听findAndModify等命令的中间状态,createCollection等纯元数据操作也不在默认范围内。

ChangeStreams 能监听哪些 CRUD 操作
ChangeStreams 原生支持 insert、update、delete、replace 四类文档级操作,也支持 drop、rename、dropDatabase 等 DDL 事件(需启用 showExpandedEvents: true)。但要注意:findAndModify、findOneAndUpdate 等命令触发的更新,最终仍归为 update 类型事件;而 createCollection 这类纯元数据操作,不在默认监听范围内。
collection.watch() 必须满足的三个硬性条件
直接调用 collection.watch() 却收不到事件?大概率卡在这三点:
- 部署不是副本集或分片集群——单机版 MongoDB(Standalone)完全不支持 ChangeStreams,因为底层依赖 oplog
- 连接的数据库未启用
majority读写关注(readConcern/writeConcern),尤其在事务场景下,缺失会导致事件丢失或报错ChangeStreamFatalError - 集合所在数据库的 oplog 太小或保留时间过短,导致恢复令牌(resume token)失效,出现
ResumeTokenNotFound
如何安全获取更新前/后的完整文档
默认情况下,update 事件只返回 updateDescription(变更字段)和 documentKey,不带原始或新文档。要拿到完整快照,必须三步齐备:
- 数据库级开启前像/后像:执行
db.adminCommand({ setClusterParameter: { changeStreamOptions: { preAndPostImages: { expireAfterSeconds: "off" } } } }) - 集合级显式启用:执行
db.runCommand({ collMod: "mycol", changeStreamPreAndPostImages: { enabled: true } }) - 监听时指定选项:
collection.watch([], { fullDocument: "required", fullDocumentBeforeChange: "required" })
漏掉任意一步,都会触发 InvalidOptions: fullDocumentBeforeChange is required but pre-images are not enabled 错误。
事务内变更的监听表现与识别方式
事务提交前的所有操作对 ChangeStreams 完全不可见;只有 commitTransaction 成功后,才会批量推送对应事件。每条事件都带两个关键字段:
-
txnNumber:类型为Long,同一事务内所有事件值相同 -
lsid:结构体,含id(UUID),用于关联同一会话下的多次事务
注意:transaction 字段并不存在于事件文档中——别在代码里查这个 key。如果需要区分事务与非事务变更,只认 txnNumber 是否存在即可。
最容易被忽略的是 oplog 保留窗口与恢复令牌的耦合关系:哪怕只是网络抖动断开几秒,若期间 oplog 已被轮转覆盖,就再也无法从断点续传——这不是驱动问题,是部署配置缺陷。


















