总结
说明
字段 | 类型 | 说明 | |||
---|---|---|---|---|---|
| 文档 | 一个 BSON 对象,用作变更流事件的标识符。恢复变更流时,此值用作
有关通过 | |||
| 时间戳 | ||||
| UUID | 标识发生更改的集合的 UUID。 6.0 版本中的新功能。
| |||
| 文档 | 一个文档,其中包含 CRUD 操作创建或修改的文档的 对于分片集合,此字段还显示文档的完整分片键。如果 | |||
| 文档 | CRUD 操作创建或修改的文档。 仅当您配置变更流时将 有关更多信息,请参阅查找更新操作的完整文档。 在 6.0 版本中进行了更改。 从 MongoDB 6.0 开始,如果您使用 | |||
| 文档 | 操作应用更改之前的文档。即文档前像。 当您使用 6.0 版本中的新功能。 | |||
| 文档 | 与事务关联的会话标识符。 只有当操作是多文档事务的一部分时才会出现。 | |||
| 文档 | 受事件影响的命名空间(数据库和/或集合)。 | |||
| 字符串 | 发生事件的集合的名称。 | |||
| 字符串 | 发生事件的数据库的名称。 | |||
| 字符串 | 变更通知报告的操作类型。 为这些变更事件返回 | |||
| 文档 | 一个文档,描述由更新操作更新或删除的字段。 | |||
updateDescription. disambiguatedPaths | 文档 | 一个文档,对 当 需要将 showExpandedEvents 选项设置为 6.1 版本新增内容。 | |||
updateDescription. removedFields | 阵列 | 一个字段数组,包含由更新操作删除的字段。 | |||
updateDescription. truncatedArrays | 阵列 | 一个文档数组,用于记录使用一个或多个以下阶段通过基于管道的更新执行的数组截断: 如果替换了整个大量,则会在 updateDescription.updatedFields 下报告截断情况。 | |||
updateDescription. truncatedArrays. field | 字符串 | 截断字段的名称。 | |||
updateDescription. truncatedArrays. newSize | 整型 | 截断数组中的元素数量。 | |||
updateDescription. updatedFields | 文档 | 一个文档,其键对应于由更新操作修改的字段。每个字段的值对应于这些字段的新值,而不是产生新值的操作。 | |||
| NumberLong | ||||
| 数据库操作的服务器日期和时间。 6.0 版本中的新功能。 |
行为
文档前期图像和期后图像
从 MongoDB 6.0 开始,如果执行以下步骤,您会看到 fullDocumentBeforeChange
文档,其中包含更改(或删除)文档之前的字段:
使用
db.createCollection()
、create
或collMod
为集合启用新的changeStreamPreAndPostImages
字段。在
db.collection.watch()
中将fullDocumentBeforeChange
设置为"required"
或"whenAvailable"
。
变更流输出中的示例 fullDocumentBeforeChange
文档:
"fullDocumentBeforeChange" : { "_id" : ObjectId("599af247bb69cd89961c986d"), "userName" : "alice123", "name" : "Alice Smith" }
有关变更流输出的完整示例,请参阅使用文档前像和后像的变更流。
如果图像属于以下情况,则前像和后像不可用于变更流事件:
在文档更新或删除操作时未对集合启用。
在
expireAfterSeconds
中设置的前像和后像保留时间后之后被删除。以下示例将整个集群上的
expireAfterSeconds
设置为100
秒:use admin db.runCommand( { setClusterParameter: { changeStreamOptions: { preAndPostImages: { expireAfterSeconds: 100 } } } } ) 以下示例返回当前的
changeStreamOptions
设置,包括expireAfterSeconds
:db.adminCommand( { getClusterParameter: "changeStreamOptions" } ) 将
expireAfterSeconds
设置为off
可使用默认保留策略:将保留前像和后像,直到从 oplog 中删除对应的变更流事件。如果变更流事件从 oplog 中删除,则无论
expireAfterSeconds
前映像和后映像保留时间如何,相应的前映像和后映像也会被删除。
其他考量:
启用前像和后像会占用存储空间并增加处理时间。仅在需要时启用前像和后像。
将变更流事件大小限制为小于 16 MiB。要限制事件大小,您可以:
将文档大小限制为 8 MB。如果其他 change stream 事件字段(例如
updateDescription
)不是很大,则可以在 change stream 输出中同时请求更新前的文档和更新后的文档。如果其他变更流事件字段(例如
updateDescription
)并不大,则仅请求变更流输出中最多 16 MiB 的文档的后像。在以下情况下,仅请求变更流输出中最多 16 MiB 的文档的前像:
文档更新仅影响文档结构或内容的一小部分,且
不会引起
replace
变更事件。replace
事件始终包含后像。
要请求前图像,请在
db.collection.watch()
中将fullDocumentBeforeChange
设置为required
或whenAvailable
。要请求后图像,您可以使用相同的方法设置fullDocument
。前像被写入
config.system.preimages
集合。config.system.preimages
集合可能会变大。要限制集合大小,可如前文所示为前映像设置expireAfterSeconds
时间。前像由后台进程异步删除。
重要
向后不兼容的功能
从 MongoDB 6.0 开始,如果您将文档前图像和后图像用于 change stream,则必须使用 collMod
命令为每个集合禁用 changeStreamPreAndPostImages,然后才能降级到早期 MongoDB 版本。
提示
有关变更流事件和输出,请参阅变更事件。
要查看集合的变化,请参阅
db.collection.watch()
。有关变更流输出的完整示例,请参阅使用文档前像和后像的变更流。
路径消歧
6.1 版本新增内容。
updateDescription
字段记录操作对文档特定字段所做的变更。这些字段描述符使用点 (.
) 作为路径分隔符,使用数字作为数组索引,因此当包含使用点或数字的字段名时,会导致一些歧义。
当 update
事件报告涉及歧义字段的变更时,disambiguatedPaths
文档会为路径键提供数组,列出每个路径组件。
注意
disambiguatedPaths
字段仅适用于使用 showExpandedEvents 选项启动的变更流
例如,一个列出了人员及其居住城镇的文档:
{ "name": "Anthony Trollope", "home.town": "Oxford", "residences": [ {"0": "Oxford"}, {"1": "Sunbury"} ] }
当更新将
home.town
字段从Oxford
修改为London
时,将生成如下所示的更新说明:"updateDescription": { "updatedFields": { "home.town": "London" }, "disambiguatedPaths": { "home.town": [ "home.town" ] } } 由于字段
home.town
包含一个句点,因此disambiguatedPaths
字段显示一个只有一个值的数组,以指示town
不是home
的子字段。当一项更新修改
residences
数组中的值以进行该变更时,将生成如下所示的更新说明:"updateDescription": { "updatedFields": { "residences.0.0": "London" }, "disambiguatedPaths": { "residences.0.0": [ "residences", 0, "0" ] } } 消除歧义的路径包括整数
0
和字符串"0"
,前者表示数组索引,后者表示嵌套文档中的字段名。
{在两种情况下,disambiguatedPath
不包括数字字段:
当路径中的第一个字段是数字字符串时(即
0.name
)。这并无歧义,因为第一个字段不能是数组索引。当数字字符串字段带有前导零时(即
0001
)。这并无歧义,因为整数不能有前导零。
更新操作
Array Updates
对数组的更新会产生 update
更改事件,但 updateDescription.updateFields
可能会显示不同的值。
示例,考虑以下文档和更新:
db.students.insertOne( { student_id: 1, scores: [ ] } ) db.students.updateOne( { student_id: 1 }, { $push: { scores: 0.85 } } ) db.students.updateOne( { student_id: 1 }, { $push: { scores: 0.94 } } ) db.students.updateOne( { student_id: 1 }, { $pull: { scores: 0.94 } } )
第一次更新对空大量进行操作。在这里,$push
会生成 update
更改事件,其中字段被具有给定值的单条目大量替换:
{ _id: { _data: '82642AD66B000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529003, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 1 }, updateDescription: { updatedFields: { scores: [ 0.85 ] }, removedFields: [], truncatedArrays: [] } }
在第二次更新操作中,大量现在包含值。$push
在大量中添加一个新条目。然后,update
更改事件将其显示为对大量中新位置(即 scores.1
)的更改:
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 1 }, updateDescription: { updatedFields: { 'scores.1': 0.94 }, removedFields: [], truncatedArrays: [] } }
如果您再次运行更新操作以将第三个分数添加到学生的记录中,则会产生修改 scores.2
的 update
更改事件。
使用 $pull
操作符删除大量项会产生一个显示新大量的变更事件:
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 1 }, updateDescription: { updatedFields: { scores: [ 0.85 ] }, removedFields: [], truncatedArrays: [] } }
数组截断
通过管道更新减少数组中元素数量的更新操作(例如使用$addFields
或$set
聚合阶段)会在truncatedArrays
字段中显示更新后的大量和新大小。
db.students.insertOne( { student_id: 2, scores: [ 0.85, 0.94, 0.78 ] } ) db.students.updateOne( { student_id: 2 }, [ { $addFields: { scores: [ 0.85, 0.94 ] } } ] ) db.students.updateOne( { student_id: 2 }, [ { $addFields: { scores: [ 0.85, 0.94, 0.78 ] } } ] )
第一次更新的变更事件(使用$addFields
阶段从 scores
字段中删除一个值)会在 truncatedArrays
字段中显示更改:
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 2 }, updateDescription: { updatedFields: {}, removedFields: [], truncatedArrays: [ { fields: "scores", newSize: 2 } ] } }
第二次更新的变更事件使用$addFields
阶段将值重新添加到 scores
字段,并在 updatedFields
字段中显示更新:
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 2 }, updateDescription: { updatedFields: { scores.2: 0.78 }, removedFields: [], truncatedArrays: [] } }
例子
以下示例说明了 update
事件:
{ "_id": { <Resume Token> }, "operationType": "update", "clusterTime": <Timestamp>, "wallTime": <ISODate>, "ns": { "db": "engineering", "coll": "users" }, "documentKey": { "_id": ObjectId("58a4eb4a30c75625e00d2820") }, "updateDescription": { "updatedFields": { "email": "alice@10gen.com" }, "removedFields": ["phoneNumber"], "truncatedArrays": [ { "field" : "vacation_time", "newSize" : 36 } ] } }
以下示例说明了使用 fullDocument : updateLookup
选项打开的变更流的 update
事件:
{ "_id": { <Resume Token> }, "operationType": "update", "clusterTime": <Timestamp>, "wallTime": <ISODate>, "ns": { "db": "engineering", "coll": "users" }, "documentKey": { "_id": ObjectId("58a4eb4a30c75625e00d2820") }, "updateDescription": { "updatedFields": { "email": "alice@10gen.com" }, "removedFields": ["phoneNumber"], "truncatedArrays": [ { "field" : "vacation_time", "newSize" : 36 } ], "disambiguatedPaths": { } }, "fullDocument": { "_id": ObjectId("58a4eb4a30c75625e00d2820"), "name": "Alice", "userName": "alice123", "email": "alice@10gen.com", "team": "replication" } }
fullDocument
文档代表已更新文档的最新多数提交版本。fullDocument
文档可能与更新操作时的文档有所不同,这取决于更新操作和文档查找之间发生的交替多数提交操作的数量。