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

如何在CouchDB现有文档中新增元素且不覆盖原有内容

CouchDB nano追加商品不覆盖已有数据解决方案

原有代码存在两个核心问题:

  1. 直接生成全新文档调用insert,没有读取原有数据,也没有携带CouchDB要求的_rev版本字段,会直接覆盖整份文档
  2. 用category、id作为对象键时没有使用动态键语法,实际会生成固定的"category"、"id"键,无法对应你传入的分类、商品ID参数

修正后的实现代码

// 注意:你需要先完成nano的初始化,替换成你自己的CouchDB地址、账号密码、数据库名
// const nano = require('nano')('http://你的账号:你的密码@127.0.0.1:5984')
// const catalogDb = nano.use('你的数据库名称')

function AddProduct(name, price, image, category, id) {
  return new Promise((resolve, reject) => {
    const docId = 'catalog'
    // 第一步:拉取现有目录文档
    catalogDb.get(docId, (getErr, existingDoc) => {
      let updatedDoc
      if (getErr) {
        // 文档不存在时,初始化全新目录结构
        if (getErr.statusCode === 404) {
          updatedDoc = {
            _id: docId,
            catalog: {}
          }
        } else {
          return reject(new Error(`获取商品目录失败,原因:${getErr.reason}`))
        }
      } else {
        // 复用已有文档数据,自动携带必填的_rev版本字段
        updatedDoc = existingDoc
      }

      // 对应分类不存在时先初始化分类
      if (!updatedDoc.catalog[category]) {
        updatedDoc.catalog[category] = {}
      }
      // 动态追加新商品,不会覆盖同分类下其他已有商品
      updatedDoc.catalog[category][id] = {
        name,
        price,
        image,
        category
      }

      // 第二步:写入更新后的完整文档
      catalogDb.insert(updatedDoc, docId, (insertErr, success) => {
        if (success) {
          resolve(name)
        } else {
          reject(new Error(`添加(${name})失败,原因:${insertErr.reason}。`))
        }
      })
    })
  })
}

注意事项

  • 如果遇到409 冲突错误,说明你拉取文档后有其他进程修改了同一份文档,重新调用一次方法拉取最新版本再写入即可
  • 如果商品量级非常大,不建议把所有商品存在同一个文档里,会导致文档体积持续膨胀,读写性能下降,可以考虑每个商品单独存为一个文档,用分类字段做筛选

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:36:03