我想进行更新插入式更新,并将我的数据插入到mongo db的嵌套数组中。
这是我的蒙戈文件。
{
"_id" : "575",
"_class" : "com.spyne.sharing.SpyneShareUserProject",
"spyneSharePhotoList" : [
{
"_id" : "fxLO68XyMR",
"spyneShareUsers" : [
{
"_id" : "chittaranjan@eventila.com",
"selectedByClient" : false
},
{
"_id" : "chittaranjan@gmail.com",
"selectedByClient" : false
}
]
},
{
"_id" : "nVpD0KoQAI",
"spyneShareUsers" : [
{
"_id" : "chittaranjan@eventila.com",
"selectedByClient" : true
}
]
},
{
"_id" : "Pm0B3Q9Igv",
"spyneShareUsers" : [
{
"_id" : "chittaranjan@gmail.com",
"selectedByClient" : true
}
]
}
]
}
我的要求是,
- 假设我有一个ID,即575(_id(
- 然后我将拥有嵌套的数组 ID,即fxLO68XyMR(spyneSharePhotoList._id(
- 然后我将嵌套电子邮件ID作为ID,即chittaranjan@eventila.com(spyneSharePhotoList.spyneShareUsers._id(和选择ByClient(布尔值(
现在我想检查这个 ID (spyneSharePhotoList.spyneShareUsers._id( 是否已经存在于所需的位置,我想根据该电子邮件 ID
更新布尔值,即selectedByClient(true/false(。
{
"_id" : "chittaranjan@gmail.com",
"selectedByClient" : false
}
在spyneShareUsers列表中。
请帮助我完成此任务。谢谢
这很可能不是最聪明的解决方案,但它应该有效:
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 }] }
)