简体   繁体   English

MongoDB 跟踪数据变化

[英]MongoDB Track data changes

I want to track changes on MongoDB Documents.我想跟踪 MongoDB 文档的更改。 The big Challenge is that MongoDB has nested Documents.最大的挑战是 MongoDB 具有嵌套的文档。

Example例子

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

after the update/change更新/更改后

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

This is a very basic example of a highly expandable real world use chase.这是高度可扩展的现实世界使用追逐的一个非常基本的例子

On a SQL Based Database, I would suggest some sort of this solution.在基于 SQL 的数据库上,我会建议某种这种解决方案。

The SQL way SQL方式

users用户

_id _ID email电子邮件
60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 cathyjarvis@delphide.com cathyjarvis@delphide.com

friends朋友们

_id _ID user_id用户身份 name名称
0 0 60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 Hancock Nelson汉考克·纳尔逊
1 1 60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 Suarez Burt苏亚雷斯·伯特
2 2 60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 Mejia Elliott梅佳艾略特

after the update/change更新/更改后

users用户

_id _ID email电子邮件
60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 cathyjarvis@delphide.com cathyjarvis@delphide.com

friends朋友们

_id _ID user_id用户身份 name名称
0 0 60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 Daphne Kline达芙妮·克莱恩
1 1 60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 Suarez Burt苏亚雷斯·伯特
2 2 60f7a8b28db7c78b57bbc217 60f7a8b28db7c78b57bbc217 Mejia Elliott梅佳艾略特

history历史

_id _ID friends_id朋友 ID field场地 preUpdate更新前 postUpdate更新后
0 0 0 0 name名称 Hancock Nelson汉考克·纳尔逊 Daphne Kline达芙妮·克莱恩

If there is an update and the change has to be tracked before the next update, this would work for NoSQL as well.如果有更新并且必须在下一次更新之前跟踪更改,这也适用于 NoSQL。 If there is a second Update, we have a second line in the SQL database and it't very clear.如果有第二个更新,我们在 SQL 数据库中有第二行,它不是很清楚。 On NoSQL, you can make a list/array of the full document and compare changes during the indexes, but there is very much redundant information which hasn't changed.在 NoSQL 上,您可以制作完整文档的列表/数组并比较索引期间的更改,但是有很多没有更改的冗余信息。

Have a look at Set Expression Operators看看设置表达式运算符

  • $setDifference
  • $setEquals
  • $setIntersection

Be ware, these operators perform set operation on arrays, treating arrays as sets.请注意,这些运算符对数组执行集合操作,将数组视为集合。 If an array contains duplicate entries, they ignore the duplicate entries.如果数组包含重复条目,它们将忽略重复条目。 They ignore the order of the elements.他们忽略元素的顺序。

In your example the update would result in在您的示例中,更新将导致

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

If the number of elements is always the same before and after the update, then you could use this one:如果更新前后元素的数量始终相同,那么您可以使用这个:

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] }
            }
         }
      }
   }
])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM