使用 MongoDB 更改流区分嵌套更新、插入和删除

del*_*hum 7 mongodb

在处理 Mongo 文档中的嵌套数组时,无论是插入、删除还是更新,都会用到 db.collection.update()

我遇到的问题是 v3.6+ 中的新更改流。

我需要一种方法来区分来自于的更改事件中的这些操作 collection.watch()

例子:

使用文档架构:

{
  id: string,
  array: [{id: string, value: string}]
}
Run Code Online (Sandbox Code Playgroud)

插入嵌套数组:

collection.updateOne(
    {id: 'some_id'},
    {$push: {'array.$': {id: 'nested_id', value: 'new nested item'} } }
)
Run Code Online (Sandbox Code Playgroud)

更改流将响应:

{
  ...
  operationType: 'update',
  updateDescription: {
    updatedFields: 'array.0': {id: 'nested_id', value: 'new nested item'}
  ... }
}
Run Code Online (Sandbox Code Playgroud)

更新嵌套数组项:

collection.updateOne(
    {id: 'some_id', 'array.id': 'nested_id'},
    {$set: {'array.$.name': 'new nested name' } }
)
Run Code Online (Sandbox Code Playgroud)

更改流将响应:

{
  ...
  operationType: 'update',
  updateDescription: {
    updatedFields: 'array.0.name': 'new nested name'
  ... }
}
Run Code Online (Sandbox Code Playgroud)

删除嵌套数组项:

collection.updateOne(
    {id: 'some_id'},
    {$pull: {array: {id: 'nested_id'} } }
)
Run Code Online (Sandbox Code Playgroud)

更改流将响应:

{
  ...
  operationType: 'update',
  updateDescription: {
    updatedFields: 'array': [...all items in array besides the one you just pulled]
  ... }
}
Run Code Online (Sandbox Code Playgroud)

我可以看到一些笨拙的方法来区分这些事件,例如'array.0.name'.split('.'),如果最后一个元素是数字,则它是嵌套插入,否则是更新或删除。这行得通,虽然我真的不喜欢它。

但似乎没有什么好方法可以区分嵌套删除和插入之间的区别。对这个问题的任何帮助都会很棒。

小智 0

您为每个操作显示的更改流响应示例仅包含一个实例,其中更新的字段指向一个数组,即删除/拉取场景。因此,检查是否updatedFields.array存在并且是一个数组。

if(Array.isArray(response.updateDescription.updatedFields["array"]) {
 // it's a $pull operation; do stuff
}
Run Code Online (Sandbox Code Playgroud)