mongodb - 如何使用 React 和 axios 更新 MongoDB 中文档的对象?

标签 mongodb mongoose

我可以更新:deviceName、macAddress 和 blacklisted,但连接对象中的任何值都不会更新(即:active、connectionURL 和配置)。 if 语句的目的是在用户将它们留空时不修改数据库中的值。

架构:

const deviceSchema = new Schema({
  deviceName: { type: String, required: true, trim: true },
  macAddress: { type: String, required: true, unique: true, trim: true },
  blacklisted: {type: Boolean, required: true},
  connection: { type: Object, required: true,
      active: { type: Boolean, required: true, trim: true },
      connectionUrl: { type: String, required: true, trim: true},
      configuration: { type: String, required: true, trim: true},
  },
}, {
  timestamps: true,
});

更新数据库:

router.route('/update/config/:id').post((req, res) => {

  Device.findById(req.params.id)
    .then(device => {
      device.macAddress = req.body.macAddress;
      device.connection.active = req.body.active;
      if (req.body.connectionUrl != '' && req.body.connectionUrl != "Choose...") {
        device.connection.connectionUrl = req.body.connectionUrl;
      }
      if (req.body.configuration != '') {
        device.connection.configuration = req.body.configuration;
      }
      device.save()
        .then(() => res.json('device configuration(s) updated!'))
        .catch(err => res.status(400).json('Error: ' + err));
    })
    .catch(err => res.status(400).json('Error: ' + err));
});

最佳答案

在 Mongoose 中,如果您为模式分配“对象”类型,它将变为 Mixed架构,这意味着几件事,但在您的情况下最重要的是 Mongoose 无法自动检测对文档该部分的更改。

您在这里寻找的可能是“嵌套路径”或“子文档”。参见 here有关两者之间差异的更多信息。

要点是,您需要更改定义架构的方式。这里有几个选项:

1。您确切地知道连接对象有哪些成员,并且总是希望能够分配给它们,即使您从未明确创建过连接也是如此。

在这种情况下,最好的选择是“嵌套路径”,其定义如下:

const deviceSchema = new Schema({
  deviceName: { type: String, required: true, trim: true },
  macAddress: { type: String, required: true, unique: true, trim: true },
  blacklisted: {type: Boolean, required: true},
  connection: { 
      active: { type: Boolean, required: true, trim: true },
      connectionUrl: { type: String, required: true, trim: true},
      configuration: { type: String, required: true, trim: true},
  },
}, {
  timestamps: true,
});

2。您确切地知道连接对象有哪些成员,但只希望在整个连接已经创建的情况下能够分配给特定成员。

在这种情况下,您将要使用子文档

const connectionSchema = new Schema({
    active: { type: Boolean, required: true, trim: true },
    connectionUrl: { type: String, required: true, trim: true },
    configuration: { type: String, required: true, trim: true },
}, { timestamps: false });

const deviceSchema = new Schema({
  deviceName: { type: String, required: true, trim: true },
  macAddress: { type: String, required: true, unique: true, trim: true },
  blacklisted: {type: Boolean, required: true},
  connection: { type: connectionSchema, required: true },
}, {
  timestamps: true,
});

编辑:引用下面评论中发布的问题:如果您希望能够从多个“deviceSchema”引用相同的 connectionSchema,您需要更改为以下内容这个:

const deviceSchema = new Schema({
  deviceName: { type: String, required: true, trim: true },
  macAddress: { type: String, required: true, unique: true, trim: true },
  blacklisted: {type: Boolean, required: true},
  connection: { type: Schema.Types.ObjectId, required: true, ref: "Connection" },
}, {
  timestamps: true,
});

在这种情况下,您还需要确定您正在显式创建两个模型(一个设备模型和一个连接模型),并确保加载连接模型设备模型,然后您将运行: DeviceModel.findOne(/*whatever*/).populate('connection') 而不是普通的“查找”方法。不过,这与最初的问题有点相去甚远。

3。你不知道连接对象的确切结构

在这里,您可以使用 built in 'Mixed' type和你一样,但它伴随着一个警告,你不能定义任何更多的 child , Mongoose 不会自动检测文档那部分的变化,这意味着 device.save() 赢了'自动更新连接对象中的任何内容。

const deviceSchema = new Schema({
  deviceName: { type: String, required: true, trim: true },
  macAddress: { type: String, required: true, unique: true, trim: true },
  blacklisted: {type: Boolean, required: true},
  connection: { type: Object, required: true },
}, {
  timestamps: true,
});

为了告诉 mongoose 连接字段已经更新,我们必须在 device.save()

关于mongodb - 如何使用 React 和 axios 更新 MongoDB 中文档的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67184580/

相关文章:

mongodb - Azure Cosmos DB 是否不支持 MongoDB/Mongoose 唯一索引?

node.js - 使用 Mongoose 的动态子文档

node.js - MongoDB $geoWithin $centerSphere 查询

node.js - 文档中的空字段会占用 Mongoose 中的空间吗?

javascript - Mongoose 在插入文档时调用字段的函数

javascript - 以下代码是使用 html、expressJS 生成 Web 表单并将提交的详细信息保存在 mongodb 中,但出现 'post' 错误, 'get' 有效

javascript - 为什么不显示在 Nodejs 和 mongoose 中创建的任何集合

json - 如何循环遍历 JSON 对象数组?

node.js - collection.findOne({query}) 不应该返回文档本身吗?

python - 使用 mongoengine 成功操作 MongoDB 的返回值是多少?