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

使用Mongoose更新MongoDB嵌套对象失败,求排查原因

问题背景

我的Mongoose Schema定义如下:

import pkg from "mongoose";

const { Schema, model, models } = pkg;

const child = new Schema({ name: String, studentid: Number});
const schema = new Schema({ name: String, age: Number, children: [child] });

const Test = model("Test", schema) 

export default Test;

数据示例:
Sample data

我希望根据age和studentid更新数组中的整个对象,编写了如下更新函数:

import { connectToDB } from "./utils/database.js";
import Test from "./models/test.js";

async function updateData() {
  await connectToDB();

  const res = Test.updateMany(
    {
      age: 34,
      name: "name2",
    },
    {
      $set: {
        "children.$[element]": {
          name: "updatedname",
          studentid: 123456789,
        },
      },
    },
    {
      arrayFilters: [
        {
          element: {
            name: "childr344en1",
            studentid: 137,
          },
        },
      ],
    },
    {upsert: true}
  );
  console.log(res)
}

await updateData();

执行该更新函数后,数据并未发生更新,请问这是什么原因?我哪里出错了?


问题原因及修复方案

你的更新代码存在两个关键问题:

1. Array Filters 语法错误

你在arrayFilters里用了element: {name: "childr344en1", studentid: 137}的写法,这是错误的。正确写法应该直接指定数组元素的字段匹配条件,element是你在更新路径中定义的占位符,需要通过它匹配数组元素的具体字段:

arrayFilters: [
  {
    "element.name": "childr344en1",
    "element.studentid": 137
  }
]

这种写法才能让MongoDB找到children数组中同时满足name和studentid条件的元素。

2. 更新选项参数拆分错误

updateMany方法的第三个参数是合并的选项对象,你把arrayFilters和upsert拆成两个独立对象传入,会导致upsert被识别为第四个参数(回调函数),无法生效,同时MongoDB也无法正确解析选项。正确做法是将两个选项合并到同一个对象:

{
  arrayFilters: [
    {
      "element.name": "childr344en1",
      "element.studentid": 137
    }
  ],
  upsert: true
}

修复后的完整代码

import { connectToDB } from "./utils/database.js";
import Test from "./models/test.js";

async function updateData() {
  await connectToDB();

  const res = Test.updateMany(
    {
      age: 34,
      name: "name2",
    },
    {
      $set: {
        "children.$[element]": {
          name: "updatedname",
          studentid: 123456789,
        },
      },
    },
    {
      arrayFilters: [
        {
          "element.name": "childr344en1",
          "element.studentid": 137
        }
      ],
      upsert: true
    }
  );
  console.log(res)
}

await updateData();

另外,建议先确认查询条件age:34和name:"name2"确实能匹配到数据库中的文档,这也是更新不生效的常见原因之一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:37:45