I want to track changes on MongoDB Documents. The big Challenge is that MongoDB has nested Documents.
[
{
"_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"
}
]
}
]
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.
users
_id | |
---|---|
60f7a8b28db7c78b57bbc217 | cathyjarvis@delphide.com |
friends
_id | user_id | name |
---|---|---|
0 | 60f7a8b28db7c78b57bbc217 | Hancock Nelson |
1 | 60f7a8b28db7c78b57bbc217 | Suarez Burt |
2 | 60f7a8b28db7c78b57bbc217 | Mejia Elliott |
users
_id | |
---|---|
60f7a8b28db7c78b57bbc217 | cathyjarvis@delphide.com |
friends
_id | user_id | name |
---|---|---|
0 | 60f7a8b28db7c78b57bbc217 | Daphne Kline |
1 | 60f7a8b28db7c78b57bbc217 | Suarez Burt |
2 | 60f7a8b28db7c78b57bbc217 | Mejia Elliott |
history
_id | friends_id | field | preUpdate | postUpdate |
---|---|---|---|---|
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. If there is a second Update, we have a second line in the SQL database and it't very clear. 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.
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] }
}
}
}
}
])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.