我想在使用 MongoTemplate 时更新数组中数组中的值
I want to update values in an array in an array while using MongoTemplate
首先,我将展示mongodb
中存储的状态。
如您所见,它是一个结构,在一个名为 comments
的列表中包含一个名为 replies
的列表。在 replies
中有一个名为 likes
.
的数组
comments : [
Object1 : {
replies : [
likes : [
0 : {},
1 : {}
]
]
},
Object2 : {
replies : [
likes : [
0 : {},
1 : {}
]
]
}
]
我想在这里做的是 insert/subtract 一个值仅来自特定 replies
结构内的 likes
数组。我目前正在使用 Spring 启动并尝试了以下操作:
Query query = new Query();
Criteria criteria = Criteria.where("_id").is(new ObjectId(postId))
.andOperator(Criteria.where("comments")
.elemMatch(Criteria.where("_id").is(new ObjectId(commentId))
.andOperator(Criteria.where("replies")
.elemMatch(Criteria.where("_id").is(new ObjectId(replyId)))
)
)
);
query.addCriteria(criteria);
Update update = new Update();
if (state) {
// remove user id
update.pull("comments.$[].replies.$.likes", new ObjectId(userId));
} else {
// add user id
update.push("comments.$[].replies.$.likes").value(new ObjectId(userId));
}
mongoTemplate.updateFirst(query, update, MyEntity.class);
是根据布尔值state
进行增减userId
的操作。作为尝试的结果,找到了一个特定的 comment
,但是 userId
被无条件地输入到 [=21 内的 replies
列表的第一个 likes
列表中=].我想要的是进入特定 reply
内的 likes
列表。我在 update.push()
中使用了错误的参数吗?如果你能告诉我如何解决它,我将不胜感激。
不是您问题的直接答案,因为我没有使用 spring 的条件生成器的经验,但这是您在 mongo 中直接执行此操作的方法,这可能有助于您理解出来了:
您可以定义 arrayfilters 以跟踪每个 comments
和 replies
的相应索引。然后,您可以使用这些索引在完全匹配的索引处推送一个新对象:
db.collection.update({
_id: "<postId>"
},
{
$push: {
"comments.$[comments].replies.$[replies].likes": {
_id: "newlyInsertedLikeId"
}
}
},
{
arrayFilters: [
{
"comments._id": "<commentId>"
},
{
"replies._id": "<replyId>"
}
]
})
这是 mongoplayground 上的示例:https://mongoplayground.net/p/eNdDXXlyi2X
首先,我将展示mongodb
中存储的状态。
如您所见,它是一个结构,在一个名为 comments
的列表中包含一个名为 replies
的列表。在 replies
中有一个名为 likes
.
comments : [
Object1 : {
replies : [
likes : [
0 : {},
1 : {}
]
]
},
Object2 : {
replies : [
likes : [
0 : {},
1 : {}
]
]
}
]
我想在这里做的是 insert/subtract 一个值仅来自特定 replies
结构内的 likes
数组。我目前正在使用 Spring 启动并尝试了以下操作:
Query query = new Query();
Criteria criteria = Criteria.where("_id").is(new ObjectId(postId))
.andOperator(Criteria.where("comments")
.elemMatch(Criteria.where("_id").is(new ObjectId(commentId))
.andOperator(Criteria.where("replies")
.elemMatch(Criteria.where("_id").is(new ObjectId(replyId)))
)
)
);
query.addCriteria(criteria);
Update update = new Update();
if (state) {
// remove user id
update.pull("comments.$[].replies.$.likes", new ObjectId(userId));
} else {
// add user id
update.push("comments.$[].replies.$.likes").value(new ObjectId(userId));
}
mongoTemplate.updateFirst(query, update, MyEntity.class);
是根据布尔值state
进行增减userId
的操作。作为尝试的结果,找到了一个特定的 comment
,但是 userId
被无条件地输入到 [=21 内的 replies
列表的第一个 likes
列表中=].我想要的是进入特定 reply
内的 likes
列表。我在 update.push()
中使用了错误的参数吗?如果你能告诉我如何解决它,我将不胜感激。
不是您问题的直接答案,因为我没有使用 spring 的条件生成器的经验,但这是您在 mongo 中直接执行此操作的方法,这可能有助于您理解出来了:
您可以定义 arrayfilters 以跟踪每个 comments
和 replies
的相应索引。然后,您可以使用这些索引在完全匹配的索引处推送一个新对象:
db.collection.update({
_id: "<postId>"
},
{
$push: {
"comments.$[comments].replies.$[replies].likes": {
_id: "newlyInsertedLikeId"
}
}
},
{
arrayFilters: [
{
"comments._id": "<commentId>"
},
{
"replies._id": "<replyId>"
}
]
})
这是 mongoplayground 上的示例:https://mongoplayground.net/p/eNdDXXlyi2X