最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Push a document if not exist, update if exist in a nested array with mongoose - Stack Overflow

programmeradmin1浏览0评论

I have mongo document and when a new order appear, I need to push it or update (increment the quantity) if an order of a part_id already exist.

   {
       user_id: '13',     
       stock: [
         {
           part_id: 'P456',
           quantity: 3
         },
         {
           part_id: 'P905',
           quantity: 8
         }
       ]
    }

I have a tried to use {upsert: true} and $inc but could not find the solution.

I have mongo document and when a new order appear, I need to push it or update (increment the quantity) if an order of a part_id already exist.

   {
       user_id: '13',     
       stock: [
         {
           part_id: 'P456',
           quantity: 3
         },
         {
           part_id: 'P905',
           quantity: 8
         }
       ]
    }

I have a tried to use {upsert: true} and $inc but could not find the solution.

Share Improve this question edited May 11, 2021 at 15:49 turivishal 36.2k7 gold badges45 silver badges68 bronze badges asked May 11, 2021 at 13:43 TKXTKX 711 silver badge6 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

I have a tried to use {upsert: true} and $inc but could not find the solution

The upsert will not support in array of object, you can try 2 queries first find and second update,

Count documents using countDocuments:

let user_id = "13";
let part_id = "P456";
let hasDoc = await YourSchema.countDocuments({ user_id: user_id, "stock.part_id": part_id });
  • Check condition if document exists then increment quantity by one
  • Else push object in stock
// Document already exists, so increment it value
if (hasDoc > 0) {
  await YourSchema.updateOne(
    { user_id: user_id, "stock.part_id": part_id },
    { $inc: { "stock.$.quantity": 1 } }
  );
} 

// Document not exists then add document
else {
  await YourSchema.updateOne(
    { user_id: user_id },
    { $push: { stock: { part_id: part_id, quantity: 1 } } }
  );
}

Second Option: You can update with aggregation pipeline starting from MongoDB 4.2,

  • $cond to check if part_id is in stock
    • yes, $map to iterate loop of stock and check condition if part_id match then add 1 in quantity otherwise return current object
    • no, add new object with part_id and quantity in stock using $concatArrays
let user_id = "13";
let part_id = "P456";
db.collection.update(
  { user_id: user_id },
  [{
    $set: {
      stock: {
        $cond: [
          { $in: [part_id, "$stock.part_id"] },
          {
            $map: {
              input: "$stock",
              in: {
                $cond: [
                  { $eq: ["$$this.part_id", part_id] },
                  {
                    part_id: "$$this.part_id",
                    quantity: { $add: ["$$this.quantity", 1] }
                  },
                  "$$this"
                ]
              }
            }
          },
          { $concatArrays: ["$stock", [{ part_id: part_id, quantity: 1 }]] }
        ]
      }
    }
  }]
)

Playground

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论