更新查询将ObjectID添加到阵列两次

时间:2018-05-15 16:50:02

标签: mongodb mongoose mongodb-query

我正在开发一个table planner应用程序,可以将guest分配给表。表模型具有以下模式:

const mongoose = require('mongoose');

mongoose.Promise = global.Promise;

const tableSchema = new mongoose.Schema({
  name: {
    type: String,
    required: 'Please provide the name of the table',
    trim: true,
  },
  capacity: {
    type: Number,
    required: 'Please provide the capacity of the table',
  },
  guests: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Guest',
  }],
});

module.exports = mongoose.model('Table', tableSchema);

可以将App(使用React DND)拖放到桌面"表"反应组件。在被丢弃在表上时,对Node.js方法发出Axios POST请求以更新数据库并将客户的对象ID添加到Table模型中的数组中:

exports.updateTableGuests = async (req, res) => {
  console.log(req.body.guestId);
  await Table.findOneAndUpdate(
    { name: req.body.tablename },
    { $push: { guests: req.body.guestId } },
    { safe: true, upsert: true },
    (err) => {
      if (err) {
        console.log(err);
      } else {
      // do stuff
      }
    },
  );
  res.send('back');
};

这是按预期工作的,除了每个被删除的guest虚拟机,Table模型的guest数组使用相同的guest虚拟机对象ID更新两次?有谁知道为什么会这样?

我已尝试记录req.body.guestID以确保它是单个值,并且还检查此函数是否未被调用两次。但这些测试都没有带来意想不到的结果。因此,我怀疑我的findOneAndUpdate查询有问题吗?

2 个答案:

答案 0 :(得分:4)

此处不要使用$push运算符,您需要使用$addToSet运算符...

  

$push运算符可以多次更新具有相同值的数组   其中,$addToSet运算符向数组添加值,除非   价值已经存在。

exports.updateTableGuests = async (req, res) => {
  console.log(req.body.guestId);
  await Table.findOneAndUpdate(
    { name: req.body.tablename },
    { $addToSet : { guests: req.body.guestId } },
    { safe: true, upsert: true },
    (err) => {
      if (err) {
        console.log(err);
      } else {
      // do stuff
      }
    },
  );
  res.send('back');
};

答案 1 :(得分:1)

我不确定addToSet是否是最佳解决方案,因为查询执行了两次。

如果您同时使用了回调和promise,则会使查询执行两次。

因此选择其中之一将使其正常工作。

像下面这样:

async updateField({ fieldName, shop_id, item }) {
    return Shop.findByIdAndUpdate(
      shop_id,
      { $push: { menuItems: item } },
      { upsert: true, new: true }
    );
  }