You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MongoTemplate更新MongoDB三层嵌套数组中指定replies的likes字段

问题原因

你当前的写法问题出在更新路径的位置运算符使用错误:普通的$位置运算符只能匹配第一层满足查询条件的数组元素,面对comments -> replies两层嵌套数组的场景,comments.$[].replies.$.likes中的$只会定位到匹配的comment下replies数组的第一个元素,因此永远操作的是第一个reply的likes数组,无法定位到你指定的replyId对应的元素。

解决方案

使用MongoDB 3.6及以上版本支持的数组筛选标识符(Array Filters)功能,为两层嵌套数组分别定义筛选规则,即可准确定位到指定comment和reply对应的likes数组。

修改后的代码如下:

// 查询条件仅需要定位到对应post文档即可,数组元素的匹配交给arrayFilter处理
Query query = Query.query(Criteria.where("_id").is(new ObjectId(postId)));

Update update = new Update();
if (state) {
    // 移除用户id
    update.pull("comments.$[comment].replies.$[reply].likes", new ObjectId(userId));
} else {
    // 新增用户id,使用addToSet避免同一个用户重复点赞插入重复数据
    update.addToSet("comments.$[comment].replies.$[reply].likes", new ObjectId(userId));
}
// 定义数组筛选规则,和更新路径中的标识符一一对应
update.filterArray(Criteria.where("comment._id").is(new ObjectId(commentId)));
update.filterArray(Criteria.where("reply._id").is(new ObjectId(replyId)));

mongoTemplate.updateFirst(query, update, MyEntity.class);

补充说明

  • 更新路径中的$[comment]、$[reply]是自定义的筛选标识符,名称和filterArray中定义的筛选条件前缀一一对应即可
  • 点赞场景推荐使用addToSet替代push,可以自动判重,避免同一个用户ID被多次插入到likes数组中,更符合业务逻辑

内容的提问来源于stack exchange,提问作者hanjiman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:54:06