support $lookup for update aggregation
We frequently denormalise either full documents or subsets to different documents in order to speed up reading, create indexes or paginate/sort on fields.
Consider a user collection and a task collection, if a task can be assigned to the user, it makes sense to just put the user document on the task they are assigned. But an update to a user now requires you to update the user both in the user collection and all tasks with that user in the tasks collection.
This can be achieved but does introduce some complexity, however the introduction of updates using aggregation pipelines could eliminate this problem if they supported the $lookup operator.
So we could achieve the desired result using two simple operations
db.collection('users').updateOne({id: '1234'}, {$set: ...})
db.collection('tasks').updateMany({"user.id": '1234'}, [
{
$lookup: {
from: 'users',
localField: 'user.id',
foreignField: 'id',
as: 'user'
}
}
]);
This would make it really simple to synchronise data between documents in different collections
-
Andreas commented
@Katya, yes that would work. but in that case we would not be able to do all this within a transaction, since $merge does not support transactions (https://docs.mongodb.com/manual/core/transactions-operations/#crud-operations)
-
How about aggregation with $merge? Would this achieve what you are looking for?
db.tasks.aggregate([
{$match: {
'user.id': '1234'
}},
{$lookup: {
from: 'users',
localField: 'user.id',
foreignField: '_id',
as: 'user',
pipeline: [{$set: {id: "$_id"}}, {$unset: "_id"}]
}},
{$set: {
user: {$first: '$user'}
}},
{$merge: {
into: 'tasks',
on: '_id'
}}
])