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

在Next.js 13中用MongoDB更新数组内指定对象的income字段

正确实现MongoDB数组元素更新的方案(Next.js 13环境)

现有MongoDB文档结构

{
    _id: ObjectId("78391283"),
    name: "Colors company",
    shops: [
        {shopID: ObjectId("123456a1cb"), income: 0},
        {shopID: ObjectId("2a1cb67890"), income: 0},
        {shopID: ObjectId("2a1cb010111"), income: 0},
        ...
      ],
}

需求

通过POST请求传入参数,匹配对应companyID的公司文档,找到其shops数组中指定shopID的对象,将该对象的income字段加上amountToAdd的数值:

{
    companyID: "78391283",
    shopID: "123456a1cb",
    amountToAdd: 200,
}

原代码的问题

你写的代码有几个关键错误:

  • 查询条件匹配错误,应该定位公司的_id(即传入的companyID),而非直接用shopID作为文档ID
  • 更新操作符使用错误,MongoDB的设置操作符是$set,不是set;累加数值需用原子操作符$inc,不能直接用parsedBody.amountToAdd + income这种写法
  • 未在查询条件中指定shops.shopID,无法定位数组中对应的店铺元素,shops.$.income里的$占位符也无法生效

正确实现代码

在Next.js 13的API路由中(App Router/Pages Router通用),正确实现如下:

import mongoose from 'mongoose';
import Company from '@/models/Company'; // 替换为你的公司模型路径

export async function POST(request) {
  const parsedBody = await request.json();
  
  // 转换为MongoDB所需的ObjectId类型
  const companyId = new mongoose.Types.ObjectId(parsedBody.companyID);
  const shopId = new mongoose.Types.ObjectId(parsedBody.shopID);
  const amountToAdd = parsedBody.amountToAdd;

  try {
    // 执行更新操作
    const updatedCompany = await Company.findOneAndUpdate(
      // 查询条件:匹配公司ID,且shops数组包含指定shopID的元素
      { 
        _id: companyId, 
        "shops.shopID": shopId 
      },
      // 更新操作:用$inc原子累加对应店铺的income
      { 
        $inc: { "shops.$.income": amountToAdd } 
      },
      // 选项:返回更新后的文档
      { new: true }
    );

    if (!updatedCompany) {
      return new Response(JSON.stringify({ message: '公司或店铺不存在' }), { status: 404 });
    }

    return new Response(JSON.stringify(updatedCompany), { status: 200 });
  } catch (error) {
    return new Response(JSON.stringify({ message: '更新失败', error: error.message }), { status: 500 });
  }
}

关键说明

  • 查询条件:同时指定_id: companyId和"shops.shopID": shopId,MongoDB会自动定位到数组中匹配的元素,$占位符代表该元素在数组中的位置
  • $inc操作符:MongoDB的原子累加操作符,能保证并发场景下数值修改的正确性,比“查询-修改-保存”的流程更安全高效
  • ObjectId转换:MongoDB的_id和shopID都是ObjectId类型,必须把传入的字符串转换为对应类型才能匹配成功

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:25:51