[SERVER-75590] db.Watch returns inconsistent updatedFields when working with arrays Created: 03/Apr/23  Updated: 31/Aug/23  Resolved: 31/Aug/23

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: 5.0.15
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: SpirIT N/A Assignee: Sebastien Mendez
Resolution: Won't Do Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Query Execution
Operating System: ALL
Steps To Reproduce:

 

db.students.insertOne( { _id: 3, scores: [] } )
const stream = db.students.watch()
db.students.updateOne( { _id: 3 }, { $push: { scores: 1 } })
stream.next()

The Output of stream:

 

{
  _id: {
    _data: '82642AD66B000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004'
  },
  operationType: 'update',
  clusterTime: Timestamp({ t: 1680529003, i: 1 }),
  ns: { db: 'communication_chat', coll: 'students' },
  documentKey: { _id: 3 },
  updateDescription: {
    updatedFields: { scores: [ 1 ] },    <===== scores is an Array
    removedFields: [],
    truncatedArrays: []
  }
}

Performing the next $push:

 

db.students.updateOne( { _id: 3 }, { $push: { scores: 2 } })
stream.next()

 

 

The Output of stream:

 

{
  _id: {
    _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004'
  },
  operationType: 'update',
  clusterTime: Timestamp({ t: 1680529011, i: 1 }),
  ns: { db: 'communication_chat', coll: 'students' },
  documentKey: { _id: 3 },
  updateDescription: {
    updatedFields: { 'scores.1': 2 },    <===== scores is a object
    removedFields: [],
    truncatedArrays: []
  }
}

 

 

What to expect?

In my opinion the first stream event should look like:

updatedFields: { 'scores.0': 1 },

instead of:

updatedFields: { scores: [ 1 ] },

 

 

Sprint: QE 2023-09-18
Participants:

 Description   

I expected to have a consistent return element inside the `updatedFields` when working with the watch and updateOne + $push functionality.

When performing a coll.Watch and then a $push on an array inside the document,
the first watch-stream returns an array in the updatedFields,
the second watch-stream returns an object.

What to expect

updatedFields: { 'scores.0': 1 },

What is actually returns

updatedFields: { scores: [ 1 ] },

 

Sidenotes:

I made sure that scores is an empty array.

I'm working with Free Mongo Cloud, in case it is important my cluster:
typing-competition-cluster  5f562f47523b020a2093688e

For JS this wouldn't be that of a problem, but with strictly typed languages like GOLang this is annoying to work around.



 Comments   
Comment by Sebastien Mendez [ 31/Aug/23 ]

The output format provided by the changestreams is intentionally aligned with the oplog format and is delivered without modification. Both the oplog and the changestreams format are designed for idempotence and size efficiency.

While we are open to exploring different approaches, making adjustments to the oplog would carry significant repercussions. Therefore, I regret to inform you that the proposed change is not planned in the near future.

Comment by Eric Sedor [ 28/Jun/23 ]

Thanks for your patience stefan.binder89@gmail.com; I'm passing this to an appropriate team to consider.

Generated at Thu Feb 08 06:30:34 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.