【问题标题】:Update query adding ObjectIDs to array twice更新查询将 ObjectID 添加到数组两次
【发布时间】:2018-10-25 14:22:00
【问题描述】:

我正在开发一个餐桌规划器应用程序,可以将客人分配到餐桌。表模型具有以下 Schema:

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);

客人可以在应用程序中(使用 React DND)拖放到“表格”React 组件中。在被放到表上后,会向 Node.js 方法发出 Axios POST 请求以更新数据库并将访客的对象 ID 添加到表模型中的数组中:

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');
};

这按预期工作,除了每个删除的来宾,表模型的来宾数组使用相同的来宾对象 ID 更新两次?有谁知道为什么会这样?

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

【问题讨论】:

  • 一旦出现问题,您是否有 Table JSON 对象的示例?我想看看“ObjectIDs to array two”的 JSON 代表,希望能了解 mongoose 的行为方式。

标签: mongodb mongoose mongodb-query


【解决方案1】:

这里不要使用$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');
};

【讨论】:

  • 这成功了。非常感谢。这是有道理的,因为您只能插入新记录,而这是对现有记录的更新。
【解决方案2】:

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

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

所以选择其中一个就可以了。

如下:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 2012-04-30
    • 2016-06-13
    • 2016-05-15
    • 2014-04-10
    相关资源
    最近更新 更多