Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions source/change-streams/change-streams.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Change Streams
:Status: Accepted
:Type: Standards
:Minimum Server Version: 3.6
:Last Modified: 2022-05-19
:Version: 1.16
:Last Modified: 2022-08-18
:Version: 1.17

.. contents::

Expand Down Expand Up @@ -307,6 +307,26 @@ If an aggregate command with a ``$changeStream`` stage completes successfully, t
* @since 4.7.0
*/
truncatedArrays: Array<Document>;

/**
* A document containing a map that associates an update path to an array containing the path components used in the update document. This data
* can be used in combination with the other fields in an `UpdateDescription` to determine the actual path in the document that was updated. This is
* necessary in cases where a key contains dot-separated strings (i.e., `{ "a.b": "c" }`) or a document contains a numeric literal string key
* (i.e., `{ "a": { "0": "a" } }`. Note that in this scenario, the numeric key can't be the top level key, because `{ "0": "a" }` is not ambiguous -
* update paths would simply be `'0'` which is unambiguous because BSON documents cannot have arrays at the top level.).
*
* Each entry in the document maps an update path to an array which contains the actual path used when the document was updated.
* For example, given a document with the following shape `{ "a": { "0": 0 } }` and an update of `{ $inc: { "a.0": 1 } }`, `disambiguatedPaths` would
* look like the following:
* {
* "a.0": ["a", "0"]
* }
*
* In each array, all elements will be returned as strings with the exception of array indices, which will be returned as 32 bit integers.
*
* @since 6.1.0
*/
disambiguatedPaths: Optional<Document>
}

The responses to a change stream aggregate or getMore have the following structures:
Expand Down Expand Up @@ -1070,3 +1090,5 @@ Changelog
+------------+------------------------------------------------------------+
| 2022-05-19 | Support new change stream events with showExpandedEvents. |
+------------+------------------------------------------------------------+
| 2022-08-17 | Support `disambiguatedPaths` in `UpdateDescription`. |
+------------+------------------------------------------------------------+
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
{
"description": "disambiguatedPaths",
"schemaVersion": "1.3",
"createEntities": [
{
"client": {
"id": "client0",
"useMultipleMongoses": false
}
},
{
"database": {
"id": "database0",
"client": "client0",
"databaseName": "database0"
}
},
{
"collection": {
"id": "collection0",
"database": "database0",
"collectionName": "collection0"
}
}
],
"runOnRequirements": [
{
"minServerVersion": "6.1.0",
"topologies": [
"replicaset",
"sharded-replicaset",
"load-balanced",
"sharded"
]
}
],
"initialData": [
{
"collectionName": "collection0",
"databaseName": "database0",
"documents": []
}
],
"tests": [
{
"description": "disambiguatedPaths is not present when showExpandedEvents is false/unset",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1,
"a": {
"1": 1
}
}
}
},
{
"name": "createChangeStream",
"object": "collection0",
"arguments": {
"pipeline": []
},
"saveResultAsEntity": "changeStream0"
},
{
"name": "updateOne",
"object": "collection0",
"arguments": {
"filter": {
"_id": 1
},
"update": {
"$set": {
"a.1": 2
}
}
}
},
{
"name": "iterateUntilDocumentOrError",
"object": "changeStream0",
"expectResult": {
"operationType": "update",
"ns": {
"db": "database0",
"coll": "collection0"
},
"updateDescription": {
"updatedFields": {
"$$exists": true
},
"removedFields": {
"$$exists": true
},
"truncatedArrays": {
"$$exists": true
},
"disambiguatedPaths": {
"$$exists": false
}
}
}
}
]
},
{
"description": "disambiguatedPaths is present on updateDescription when an ambiguous path is present",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1,
"a": {
"1": 1
}
}
}
},
{
"name": "createChangeStream",
"object": "collection0",
"arguments": {
"pipeline": [],
"showExpandedEvents": true
},
"saveResultAsEntity": "changeStream0"
},
{
"name": "updateOne",
"object": "collection0",
"arguments": {
"filter": {
"_id": 1
},
"update": {
"$set": {
"a.1": 2
}
}
}
},
{
"name": "iterateUntilDocumentOrError",
"object": "changeStream0",
"expectResult": {
"operationType": "update",
"ns": {
"db": "database0",
"coll": "collection0"
},
"updateDescription": {
"updatedFields": {
"$$exists": true
},
"removedFields": {
"$$exists": true
},
"truncatedArrays": {
"$$exists": true
},
"disambiguatedPaths": {
"a.1": [
"a",
"1"
]
}
}
}
}
]
},
{
"description": "disambiguatedPaths returns array indices as integers",
"operations": [
{
"name": "insertOne",
"object": "collection0",
"arguments": {
"document": {
"_id": 1,
"a": [
{
"1": 1
}
]
}
}
},
{
"name": "createChangeStream",
"object": "collection0",
"arguments": {
"pipeline": [],
"showExpandedEvents": true
},
"saveResultAsEntity": "changeStream0"
},
{
"name": "updateOne",
"object": "collection0",
"arguments": {
"filter": {
"_id": 1
},
"update": {
"$set": {
"a.0.1": 2
}
}
}
},
{
"name": "iterateUntilDocumentOrError",
"object": "changeStream0",
"expectResult": {
"operationType": "update",
"ns": {
"db": "database0",
"coll": "collection0"
},
"updateDescription": {
"updatedFields": {
"$$exists": true
},
"removedFields": {
"$$exists": true
},
"truncatedArrays": {
"$$exists": true
},
"disambiguatedPaths": {
"a.0.1": [
"a",
{
"$$type": "int"
},
"1"
]
}
}
}
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
description: "disambiguatedPaths"
schemaVersion: "1.3"
createEntities:
- client:
id: &client0 client0
useMultipleMongoses: false
- database:
id: &database0 database0
client: *client0
databaseName: *database0
- collection:
id: &collection0 collection0
database: *database0
collectionName: *collection0

runOnRequirements:
- minServerVersion: "6.1.0"
topologies: [ replicaset, sharded-replicaset, load-balanced, sharded ]

initialData:
- collectionName: *collection0
databaseName: *database0
documents: []

tests:
- description: "disambiguatedPaths is not present when showExpandedEvents is false/unset"
operations:
- name: insertOne
object: *collection0
arguments:
document: { _id: 1, 'a': { '1': 1 } }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[opt] You could use " to be consistent with the other spec tests.

- name: createChangeStream
object: *collection0
arguments: { pipeline: [] }
saveResultAsEntity: &changeStream0 changeStream0
- name: updateOne
object: *collection0
arguments:
filter: { _id: 1 }
update: { $set: { 'a.1': 2 } }
- name: iterateUntilDocumentOrError
object: *changeStream0
expectResult:
operationType: "update"
ns: { db: *database0, coll: *collection0 }
updateDescription:
updatedFields: { $$exists: true }
removedFields: { $$exists: true }
truncatedArrays: { $$exists: true }
disambiguatedPaths: { $$exists: false }

- description: "disambiguatedPaths is present on updateDescription when an ambiguous path is present"
operations:
- name: insertOne
object: *collection0
arguments:
document: { _id: 1, 'a': { '1': 1 } }
- name: createChangeStream
object: *collection0
arguments: { pipeline: [], showExpandedEvents: true }
saveResultAsEntity: &changeStream0 changeStream0
- name: updateOne
object: *collection0
arguments:
filter: { _id: 1 }
update: { $set: { 'a.1': 2 } }
- name: iterateUntilDocumentOrError
object: *changeStream0
expectResult:
operationType: "update"
ns: { db: *database0, coll: *collection0 }
updateDescription:
updatedFields: { $$exists: true }
removedFields: { $$exists: true }
truncatedArrays: { $$exists: true }
disambiguatedPaths: { 'a.1': ['a', '1'] }

- description: "disambiguatedPaths returns array indices as integers"
operations:
- name: insertOne
object: *collection0
arguments:
document: { _id: 1, 'a': [{'1': 1 }] }
- name: createChangeStream
object: *collection0
arguments: { pipeline: [], showExpandedEvents: true }
saveResultAsEntity: &changeStream0 changeStream0
- name: updateOne
object: *collection0
arguments:
filter: { _id: 1 }
update: { $set: { 'a.0.1': 2 } }
- name: iterateUntilDocumentOrError
object: *changeStream0
expectResult:
operationType: "update"
ns: { db: *database0, coll: *collection0 }
updateDescription:
updatedFields: { $$exists: true }
removedFields: { $$exists: true }
truncatedArrays: { $$exists: true }
disambiguatedPaths: { 'a.0.1': ['a', { $$type: 'int' }, '1'] }