Скорее всего, это не самое умное решение, но оно должно работать:
shareUserProject = {
id: "575",
PhotoListId: "fxLO68XyMR",
ShareUserId: "chittaranjan_new@eventila.com"
}
db.collection.aggregate([
{ $match: { _id: shareUserProject.id } },
{
$facet: {
root: [{ $match: {} }],
update: [
{ $unwind: "$spyneSharePhotoList" },
{ $match: { "spyneSharePhotoList._id": shareUserProject.PhotoListId } },
{
$set: {
"spyneSharePhotoList.spyneShareUsers": {
$concatArrays: [
{
$filter: {
input: "$spyneSharePhotoList.spyneShareUsers",
cond: { $ne: ["$$this._id", shareUserProject.ShareUserId] }
}
},
[{
_id: shareUserProject.ShareUserId,
selectedByClient: { $in: [shareUserProject.ShareUserId, "$spyneSharePhotoList.spyneShareUsers._id"] }
}]
]
}
}
}
]
}
},
{ $unwind: "$root" },
{ $unwind: "$update" },
{
$set: {
"root.spyneSharePhotoList": {
$concatArrays: [
["$update.spyneSharePhotoList"],
{
$filter: {
input: "$root.spyneSharePhotoList",
cond: { $ne: ["$$this._id", shareUserProject.PhotoListId] }
}
}
]
}
}
},
{ $replaceRoot: { newRoot: "$root" } }
]).forEach(function (doc) {
db.collection.replaceOne({ _id: doc._id }, doc);
})
Я не проверял, все ли операторы доступны в MongoDB 3.5
Моя цель была обработать все в агрегационном конвейере и запустить только один replaceOne()
в конце.
Здесь другое решение на основе оператора $ map :
db.collection.aggregate([
{ $match: { _id: shareUserProject.id } },
{
$set: {
spyneSharePhotoList: {
$map: {
input: "$spyneSharePhotoList",
as: "photoList",
in: {
$cond: {
if: { $eq: [ "$$photoList._id", shareUserProject.PhotoListId ] },
then: {
"_id": "$$photoList._id",
spyneShareUsers: {
$cond: {
if: { $in: [ shareUserProject.ShareUserId, "$$photoList.spyneShareUsers._id" ] },
then: {
$map: {
input: "$$photoList.spyneShareUsers",
as: "shareUsers",
in: {
$cond: {
if: { $eq: [ "$$shareUsers._id", shareUserProject.ShareUserId ] },
then: { _id: shareUserProject.ShareUserId, selectedByClient: true },
else: "$$shareUsers"
}
}
}
},
else: {
$concatArrays: [
"$$photoList.spyneShareUsers",
[ { _id: shareUserProject.ShareUserId, selectedByClient: false } ]
]
}
}
}
},
else: "$$photoList"
}
}
}
}
}
}
]).forEach(function (doc) {
db.collection.replaceOne({ _id: doc._id }, doc);
})
Вы можете достичь того же результат также с двумя обновлениями:
shareUserProject = {
id: "575",
PhotoListId: "fxLO68XyMR_x",
ShareUserId: "chittaranjan_new@gmail.com"
}
ret = db.collection.updateOne(
{ _id: shareUserProject.id },
{ $pull: { "spyneSharePhotoList.$[photoList].spyneShareUsers": { _id: shareUserProject.ShareUserId } } },
{ arrayFilters: [{ "photoList._id": shareUserProject.PhotoListId }] }
)
db.collection.updateOne(
{ _id: shareUserProject.id },
{ $push: { "spyneSharePhotoList.$[photoList].spyneShareUsers": { _id: shareUserProject.ShareUserId, selectedByClient: ret.modifiedCount == 1 } } },
{ arrayFilters: [{ "photoList._id": shareUserProject.PhotoListId }] }
)