在MongoDB中是否有一种有条件地同时更新和推送的方法?

huangapple go评论71阅读模式
英文:

Is there a way to update and push at the same time conditionally in Mongodb?

问题

我明白你想要的是将新的购物车项目添加到用户的购物车中,并且在购物车中已经存在相同选项的情况下增加数量,如果购物车中不存在相同选项,则创建新的购物车项目。以下是你可以采用的方法:

router.post("/addToCart", auth, async (req, res) => {
  const rootProductDoc = await Product.findOne({
    _id: req.body.productId,
  }).exec();

  User.findOne({ _id: req.user._id }, async (err, result) => {
    if (err) {
      return res.status(400).json({ success: false, err });
    }

    // 检查购物车中是否已存在相同选项
    const duplicateCartItem = result.cart.find((cartItem) => {
      return (
        cartItem.id === rootProductDoc.id &&
        JSON.stringify(cartItem.option) === JSON.stringify(req.body.option)
      );
    });

    if (duplicateCartItem) {
      // 如果存在相同选项的购物车项目,增加数量
      duplicateCartItem.quantity += 1;
    } else {
      // 如果不存在相同选项的购物车项目,创建新的购物车项目
      const newCartItem = {
        id: rootProductDoc.id,
        quantity: 1,
        option: req.body.option,
      };
      result.cart.push(newCartItem);
    }

    try {
      await result.save(); // 保存更新后的购物车

      return res.status(200).send(result.cart);
    } catch (saveErr) {
      return res.status(400).json({ success: false, err: saveErr });
    }
  });
});

这段代码首先检查用户的购物车中是否已经存在相同选项的购物车项目。如果存在,它会增加数量,如果不存在,它会创建一个新的购物车项目。最后,它保存更新后的购物车并返回购物车内容。

希望这有助于你实现所需的功能!

英文:

First of all, I apologize that the writing may not be natural because I used a translator.

I just started coding, and I don't know what's better or not. I will be grateful for your comments and help.

I'm currently implementing the cart function of the shopping mall.

If the status of the user's current cart is as follows:

let currentCart = [
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1,
  },
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 2",
    },
    quantity: 1,
  },
];

When a user tries to add a new item to the cart as shown below:

let newCart = [
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1,
  },
  {
    id: "BBBBB",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1,
  },
];

The results I want are as follows:

let result = [
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 2, // The cart that already exists adds quantity.
  },
  {
    id: "AAAAA",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 2",
    },
    quantity: 1,
  },
  {
    id: "BBBBB",
    option: {
      delivery: "pickup",
      date: "2023.01.06",
      request: "request 1",
    },
    quantity: 1, // Cart that doesn't exist will be newly added.
  },
];

How can I implement these functions?

I tried the following code:

router.post("/addToCart", auth, async (req, res) => {
  const rootProductDoc = await Product.findOne({
    _id: req.body.productId,
  }).exec();

  User.findOne({ _id: req.user._id }, (err, result) => {
    let existingOptionStr = result.cart.map((cartItem) => {
      return JSON.stringify(cartItem.option);
    });

    let duplicateOption = req.body.option.filter((createdOption) => {
      return existingOptionStr.includes(JSON.stringify(createdOption));
    });

    if (duplicateOption) {
      for (let i = 0; i < duplicateOption.length; i++) {
        User.updateMany(
          { _id: req.user._id, "cart.option": duplicateOption[i] },
          {
            $inc: { "cart.$.quantity": 1 },
          },
          {
            new: true,
          },
          (err, result) => {
            if (err) {
              return res.status(400).json({ success: false, err });
            } else {
              return res.status(200).send(result.cart);
            }
          }
        );
      }
    }
  });
});

According to the code above, updating the information that was previously contained in the cart works well.

But I'm currently stuck at implementing the remaining cases.

I want to run the same function as the code below at the same time.

User.updateMany(
  {
    _id: req.user._id,
  },
  {
    $push: {
      cart: {
        rootProductDoc: rootProductDoc,
        id: rootProductDoc.id,
        quantity: 1,
        option: req.body.option,
      },
    },
  },
  {
    new: true,
  },
  (err, result) => {
    if (err) {
      return res.status(400).json({ success: false, err });
    } else {
      return res.status(200).send(result.cart);
    }
  }
);

What should I do to get the expected result as above?

答案1

得分: 0

首先,检查购物车,检查物品是否存在。如果存在,则更新物品的数量。如果物品不存在,则将新物品添加到购物车。

例如:

router.post("/addToCart", auth, async (req, res) => {
  const rootProductDoc = await Product.findOne({
    _id: req.body.productId
  }).exec()

  User.findOne({
    _id: req.user._id
  }, (err, result) => {
    let existingItem = result.cart.find((item) => {
      return item.id === rootProductDoc.id && item.option === req.body.option
    })

    if (existingItem) {
      // 物品在购物车中存在,因此更新物品的数量
      User.updateMany({
          _id: req.user._id,
          "cart._id": existingItem._id
        }, {
          $inc: {
            "cart.$.quantity": 1
          }
        }, {
          new: true
        },
        (err, result) => {
          if (err) {
            return res.status(400).json({
              success: false,
              err
            })
          } else {
            return res.status(200).send(result.cart)
          }
        }
      )
    } else {
      // 物品不存在,因此添加到购物车
      User.updateMany({
          _id: req.user._id
        }, {
          $push: {
            cart: {
              rootProductDoc: rootProductDoc,
              id: rootProductDoc.id,
              quantity: 1,
              option: req.body.option
            }
          }
        }, {
          new: true
        },
        (err, result) => {
          if (err) {
            return res.status(400).json({
              success: false,
              err
            })
          } else {
            return res.status(200).send(result.cart)
          }
        }
      )
    }
  })
})

如果遇到任何问题,请告诉我。

英文:

First of all, Check the cart, Item is exists or not. if exists, then update the quantity of the item, If item is not exists then add new item in the cart.

For example:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

router.post(&quot;/addToCart&quot;, auth, async(req, res) =&gt; {
const rootProductDoc = await Product.findOne({
_id: req.body.productId
}).exec()
User.findOne({
_id: req.user._id
}, (err, result) =&gt; {
let existingItem = result.cart.find((item) =&gt; {
return item.id === rootProductDoc.id &amp;&amp; item.option === req.body.option
})
if (existingItem) {
//  item exists in cart, so update the quantity of the item
User.updateMany({
_id: req.user._id,
&quot;cart._id&quot;: existingItem._id
}, {
$inc: {
&quot;cart.$.quantity&quot;: 1
}
}, {
new: true
},
(err, result) =&gt; {
if (err) {
return res.status(400).json({
success: false,
err
})
} else {
return res.status(200).send(result.cart)
}
}
)
} else {
// item does not exist, so add to the cart
User.updateMany({
_id: req.user._id
}, {
$push: {
cart: {
rootProductDoc: rootProductDoc,
id: rootProductDoc.id,
quantity: 1,
option: req.body.option
}
}
}, {
new: true
},
(err, result) =&gt; {
if (err) {
return res.status(400).json({
success: false,
err
})
} else {
return res.status(200).send(result.cart)
}
}
)
}
})
})

<!-- end snippet -->

If you face any problem. Please let me know

huangapple
  • 本文由 发表于 2023年1月6日 18:25:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75029709.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定