【问题标题】:MongoDB Track data changesMongoDB 跟踪数据更改
【发布时间】:2021-09-28 12:30:36
【问题描述】:

我想跟踪 MongoDB 文档的更改。最大的挑战是 MongoDB 有嵌套的文档。

示例

[
  {
    "_id": "60f7a86c0e979362a25245eb",
    "email": "walltownsend@delphide.com",
    "friends": [
      {
        "name": "Hancock Nelson"
      },
      {
        "name": "Owen Dotson"
      },
      {
        "name": "Cathy Jarvis"
      }
    ]
  }
]

更新/更改后

[
  {
    "_id": "60f7a86c0e979362a25245eb",
    "email": "walltownsend@delphide.com",
    "friends": [
      {
        "name": "Daphne Kline"     //<------
      },
      {
        "name": "Owen Dotson"
      },
      {
        "name": "Cathy Jarvis"
      }
    ]
  }
]

这是一个非常基本的示例,是一个高度可扩展的现实世界使用追逐。

在基于 SQL 的数据库上,我建议使用某种 this 解决方案。

SQL方式

用户

_id email
60f7a8b28db7c78b57bbc217 cathyjarvis@delphide.com

朋友

_id user_id name
0 60f7a8b28db7c78b57bbc217 Hancock Nelson
1 60f7a8b28db7c78b57bbc217 Suarez Burt
2 60f7a8b28db7c78b57bbc217 Mejia Elliott

更新/更改后

用户

_id email
60f7a8b28db7c78b57bbc217 cathyjarvis@delphide.com

朋友

_id user_id name
0 60f7a8b28db7c78b57bbc217 Daphne Kline
1 60f7a8b28db7c78b57bbc217 Suarez Burt
2 60f7a8b28db7c78b57bbc217 Mejia Elliott

历史

_id friends_id field preUpdate postUpdate
0 0 name Hancock Nelson Daphne Kline

如果有更新并且必须在下一次更新之前跟踪更改,这也适用于 NoSQL。如果有第二个更新,我们在 SQL 数据库中有第二行,它不是很清楚。在 NoSQL 上,您可以制作完整文档的列表/数组,并比较索引期间的更改,但是有很多冗余信息没有更改。

【问题讨论】:

  • 您喜欢跟踪新的和删除的元素还是只跟踪现有元素的更新?如果是,您是否同时添加/删除/修改?
  • 在数组中,顺序很重要。如果您的名字相同,但顺序不同,会发生什么?
  • 是的,舒尔。数组 = 索引。但对于我的示例,我只想要数组,无论数据库应用哪种排序。

标签: database mongodb


【解决方案1】:

看看Set Expression Operators

  • $setDifference
  • $setEquals
  • $setIntersection

请注意,这些运算符对数组执行集合操作,将数组视为集合。如果数组包含重复条目,它们将忽略重复条目。他们忽略了元素的顺序。

在您的示例中,更新将导致

removed: [ {name: "Hancock Nelson" } ],
added: [ {name: "Daphne Kline" } ]

如果元素的数量在更新前后总是相同的,那么你可以使用这个:

db.collection.insertOne({
   friends: [
      { "name": "Hancock Nelson" },
      { "name": "Owen Dotson" },
      { "name": "Cathy Jarvis" }
   ],
   updated_friends: [
      { "name": "Daphne Kline" },
      { "name": "Owen Dotson" },
      { "name": "Cathy Jarvis" }
   ]
})


db.collection.aggregate([
   {
      $set: {
         difference: {
            $map: {
               input: { $range: [0, { $size: "$friends" }] },
               as: "i",
               in: {
                  $cond: {
                     if: {
                        $eq: [
                           { $arrayElemAt: ["$friends", "$$i"] },
                           { $arrayElemAt: ["$updated_friends", "$$i"] }
                        ]
                     },
                     then: null,
                     else: {
                        old: { $arrayElemAt: ["$friends", "$$i"] },
                        new: { $arrayElemAt: ["$updated_friends", "$$i"] }
                     }
                  }
               }
            }
         }
      }
   },
   {
      $set: {
         difference: {
            $filter: {
               input: "$difference",
               cond: { $ne: ["$$this", null] }
            }
         }
      }
   }
])

【讨论】:

  • 看起来不错,也许是我想要的。我会在接下来的几天里试试这个。在本例中,您在用户文档中添加了一个数组类型的新字段?
  • 是的,这更像是一个可视化函数的例子。
猜你喜欢
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 2021-05-16
  • 2018-07-07
相关资源
最近更新 更多