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

如何用JavaScript和mongojs将单文档插入两个MongoDB集合?

解决mongojs同时插入多个MongoDB集合的问题

你之前尝试的(db.completeds&&db.deliveredhistory)insert(data)写法是行不通的——因为mongojs的集合insert是异步操作,每个集合的插入都需要单独调用并处理其执行结果。下面给你两种实用的解决方案:

方案1:回调嵌套(简单直接)

在第一个集合插入成功的回调里,再执行第二个集合的插入,等两个操作都完成后再返回响应。同时要做好每一步的错误处理:

function route(app){
 app.post('/shipper/completed',function(req, res){
  var item_id = req.body.item_id
  var id = mongojs.ObjectId(item_id);
  
  db.delivereds.findAndModify({
   "query":{ "_id": id },
   "remove": false
  }, function(err, data) {
   if (err) {
    return res.json({ status:400, message:"Failed to fetch delivery data", err:err })
   }
   if (!data) {
    console.log("fake number")
    return res.json({ status: 403, message:'This load is not available for accepting' })
   }

   // 先插入completeds集合
   db.completeds.insert(data, function(err, completedResult) {
    if (err) {
     return res.json({ status:400, message:"Failed to mark as complete", err:err })
    }

    // 再插入deliveredhistory集合
    db.deliveredhistory.insert(data, function(err, historyResult) {
     if (err) {
      return res.json({ status:400, message:"Failed to record delivery history", err:err })
     }

     // 两个插入都成功,返回最终响应
     res.json({ 
      status:200, 
      message:"Job successfully completed and history saved", 
      completedData: completedResult,
      historyData: historyResult
     });
    })
   })
  })
 })
}

方案2:Promise并行处理(优雅避免回调地狱)

把mongojs的异步方法包装成Promise,再用Promise.all并行执行两个插入操作,代码结构会更清晰:

// 封装一个Promise版的插入方法
function insertToCollection(collection, data) {
 return new Promise((resolve, reject) => {
  collection.insert(data, (err, result) => {
   err ? reject(err) : resolve(result);
  })
 })
}

// 同样给findAndModify封装Promise
function findAndModify(collection, queryOpts) {
 return new Promise((resolve, reject) => {
  collection.findAndModify(queryOpts, (err, data) => {
   err ? reject(err) : resolve(data);
  })
 })
}

function route(app){
 app.post('/shipper/completed', async function(req, res){
  try {
   var item_id = req.body.item_id
   var id = mongojs.ObjectId(item_id);
   
   // 获取目标数据
   const data = await findAndModify(db.delivereds, {
    "query":{ "_id": id },
    "remove": false
   })

   if (!data) {
    console.log("fake number")
    return res.json({ status: 403, message:'This load is not available for accepting' })
   }

   // 并行执行两个插入操作
   const [completedResult, historyResult] = await Promise.all([
    insertToCollection(db.completeds, data),
    insertToCollection(db.deliveredhistory, data)
   ])

   // 全部成功后返回响应
   res.json({ 
    status:200, 
    message:"Job successfully completed and history recorded", 
    completedData: completedResult,
    historyData: historyResult
   });

  } catch (err) {
   // 统一捕获所有错误
   res.json({ status:400, message:"Operation failed", err:err })
  }
 })
}

额外提醒

如果需要强原子性(两个插入要么都成功,要么都失败),mongojs本身不支持跨集合事务,这时候你需要使用MongoDB 4.0+的事务功能(要求副本集部署),不过大部分场景下上面的方案已经足够满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:00:25