如何在双嵌套数组中添加或删除元素?
How to add or remove a element in double nested array?
文档示例:
{
postId:'232323',
post:'This is my first post',
commentsOnPost:[
{
commentId:'232323_8888',
comment:'Congrats',
repliesOnPost:[
{
replyId:'232323_8888_66666',
reply:'Thanks',
likesOnReply:['user1','user5','user3'],
}
]
}
]
}
如果 likesOnReply
中不存在用户,我想在 likesOnReply
中添加 userid
,如果存在,同样从 likesOnReply
中删除 userid
。
我试过这样,但不能正常工作
await collection('post').findOneAndUpdate(
{
postId: postId,
'commentsOnPost.commentId': commentId,
'commentsOnPost.repliesOnPost.replyId': replyId
},
{
$push: { 'commentsOnPost.$[].repliesOnPost.$.likes': userid },
},
);
没有直接的方法可以在单个查询中执行拉取或推送操作,
有两种方法,
1) 使用 2 个查询查找和更新:
- 使用arrayFilters更新嵌套数组元素
$push
插入元素
$pull
删除元素
var post = await collection('post').findOne({
posted: postId,
ommentsOnPost: {
$elemMatch: {
commentId: commentId,
repliesOnPost: {
$elemMatch: {
replyId: replyId
likesOnReply: userid
}
}
}
}
});
var updateOperator = "$push";
// FOUND USER ID THEN DO REMOVE OPERATION
if (post) updateOperator = "$pull";
// QUERY
await collection('post').updateOne(
{ postId: postId },
{
[updateOperator]: {
"commentsOnPost.$[c].repliesOnPost.$[r].likesOnReply": userid
}
},
{
arrayFilters: [
{ "c.commentId": commentId },
{ "r.replyId": replyId }
]
}
)
2) Update with aggregation pipeline 从 MongoDB 开始 4.2:
$map
循环commentsOnPost
数组检查条件如果commentId
匹配则进入下一个过程否则return现有对象
$mergeObjects
将当前对象与更新的字段合并
$map
迭代 repliesOnPost
数组的循环并检查条件,如果 replyId
匹配则转到下一个过程,否则 return 现有对象
- 检查
likesOnReply
的条件有 userid
然后使用 $filter
删除,否则使用 $concatArrays
插入
await collection('post').findOneAndUpdate(
{ postId: "232323" },
[{
$set: {
commentsOnPost: {
$map: {
input: "$commentsOnPost",
in: {
$cond: [
{ $eq: ["$$this.commentId", commentId] },
{
$mergeObjects: [
"$$this",
{
repliesOnPost: {
$map: {
input: "$$this.repliesOnPost",
in: {
$cond: [
{ $eq: ["$$this.replyId", replyId] },
{
$mergeObjects: [
"$$this",
{
likesOnReply: {
$cond: [
{ $in: [userid, "$$this.likesOnReply"] },
{
$filter: {
input: "$$this.likesOnReply",
cond: { $ne: ["$$this", userid] }
}
},
{
$concatArrays: ["$$this.likesOnReply", [userid]]
}
]
}
}
]
},
"$$this"
]
}
}
}
}
]
},
"$$this"
]
}
}
}
}
}]
)
文档示例:
{
postId:'232323',
post:'This is my first post',
commentsOnPost:[
{
commentId:'232323_8888',
comment:'Congrats',
repliesOnPost:[
{
replyId:'232323_8888_66666',
reply:'Thanks',
likesOnReply:['user1','user5','user3'],
}
]
}
]
}
如果 likesOnReply
中不存在用户,我想在 likesOnReply
中添加 userid
,如果存在,同样从 likesOnReply
中删除 userid
。
我试过这样,但不能正常工作
await collection('post').findOneAndUpdate(
{
postId: postId,
'commentsOnPost.commentId': commentId,
'commentsOnPost.repliesOnPost.replyId': replyId
},
{
$push: { 'commentsOnPost.$[].repliesOnPost.$.likes': userid },
},
);
没有直接的方法可以在单个查询中执行拉取或推送操作,
有两种方法,
1) 使用 2 个查询查找和更新:
- 使用arrayFilters更新嵌套数组元素
$push
插入元素$pull
删除元素
var post = await collection('post').findOne({
posted: postId,
ommentsOnPost: {
$elemMatch: {
commentId: commentId,
repliesOnPost: {
$elemMatch: {
replyId: replyId
likesOnReply: userid
}
}
}
}
});
var updateOperator = "$push";
// FOUND USER ID THEN DO REMOVE OPERATION
if (post) updateOperator = "$pull";
// QUERY
await collection('post').updateOne(
{ postId: postId },
{
[updateOperator]: {
"commentsOnPost.$[c].repliesOnPost.$[r].likesOnReply": userid
}
},
{
arrayFilters: [
{ "c.commentId": commentId },
{ "r.replyId": replyId }
]
}
)
2) Update with aggregation pipeline 从 MongoDB 开始 4.2:
$map
循环commentsOnPost
数组检查条件如果commentId
匹配则进入下一个过程否则return现有对象$mergeObjects
将当前对象与更新的字段合并$map
迭代repliesOnPost
数组的循环并检查条件,如果replyId
匹配则转到下一个过程,否则 return 现有对象- 检查
likesOnReply
的条件有userid
然后使用$filter
删除,否则使用$concatArrays
插入
await collection('post').findOneAndUpdate(
{ postId: "232323" },
[{
$set: {
commentsOnPost: {
$map: {
input: "$commentsOnPost",
in: {
$cond: [
{ $eq: ["$$this.commentId", commentId] },
{
$mergeObjects: [
"$$this",
{
repliesOnPost: {
$map: {
input: "$$this.repliesOnPost",
in: {
$cond: [
{ $eq: ["$$this.replyId", replyId] },
{
$mergeObjects: [
"$$this",
{
likesOnReply: {
$cond: [
{ $in: [userid, "$$this.likesOnReply"] },
{
$filter: {
input: "$$this.likesOnReply",
cond: { $ne: ["$$this", userid] }
}
},
{
$concatArrays: ["$$this.likesOnReply", [userid]]
}
]
}
}
]
},
"$$this"
]
}
}
}
}
]
},
"$$this"
]
}
}
}
}
}]
)