如果通过 Mongoose 在 Mongodb 的另一个文档中存在引用,有啥更好的方法可以防止文档被删除?

Posted

技术标签:

【中文标题】如果通过 Mongoose 在 Mongodb 的另一个文档中存在引用,有啥更好的方法可以防止文档被删除?【英文标题】:What is a better way to prevent document from deleting if a reference is present in another document in Mongodb via Mongoose?如果通过 Mongoose 在 Mongodb 的另一个文档中存在引用,有什么更好的方法可以防止文档被删除? 【发布时间】:2017-02-22 04:59:21 【问题描述】:

我正在使用以下堆栈创建一个 webapp:

节点 快递 MongoDB 猫鼬

我已将应用程序构建为 MVC 结构。

有 Customer、OrderReceived 和 OrderSent 架构。 OrderReceived 和 OrderSent 架构引用客户架构。 Abridge 架构结构如下:

客户

const mongoose = require('mongoose');

const customerSchema = mongoose.Schema(
  companyName: String,
  firstName:  type: String, required: true,
  lastName:  type: String, required: true
);

module.exports = mongoose.model('Customer', customerSchema);

订单已收到

const mongoose = require('mongoose');

const orderReceivedSchema = mongoose.Schema(
  receivedDate:  type: Date, required: true,
  customer: type: mongoose.Schema.Types.ObjectId, ref: 'Customer', required: true
);

module.exports = mongoose.model('OrderReceived', orderReceivedSchema);

订单发送

const mongoose = require('mongoose');

const orderSentSchema = mongoose.Schema(
  sentDate:  type: Date, required: true,
  customer: type: mongoose.Schema.Types.ObjectId, ref: 'Customer', required: true
);

module.exports = mongoose.model('OrderSent', orderSentSchema);

当要求删除客户文档时,我想检查该文档是否被 OrderReceived 或 OrderSent 文档引用。如果存在,我想阻止删除客户文档。

我想出的解决方案是在客户的控制器中进行检查,如下:

CustomerController#destroy 这个处理删除请求:

destroy(req, res)
    OrderReceived.count(customer: req.params.id, (error, orderLength)=>
      if (error) res.send(error);
      if (orderLength<1)
        OrderSent.count('customer.customer': req.params.id, (error, orderLength)=>
          if (error) res.send(error);
          if (orderLength<1)
            Customer.remove(_id: req.params.id, error => 
              if (error) res.send(error);
              res.json(message: 'Customer successfully deleted.');
            );
           else 
            res.status(409).json(message: 'There are orders sent using the Customer. Datum could not be deleted');
          
        );
       else 
        res.status(409).json(message: 'There are orders received using the Customer. Datum could not be deleted.');
      
    );
  

有没有更好的方法来做到这一点?我还有其他模型也依赖于客户文档,而这段代码只会变得更加混乱。 请帮忙。

【问题讨论】:

请看这篇帖子***.com/questions/39914262/… 【参考方案1】:

当您创建OrderReceivedOrderSent 时,也将它的引用保存在Customer 中。 因此,在删除它之前,您可以简单地检查它们是否为空。 您的客户架构如下:

const customerSchema = mongoose.Schema(
    companyName: String,
    firstName:  type: String, required: true,
    lastName:  type: String, required: true,
    ordersSent: [type: mongoose.Schema.Types.ObjectId, ref: 'OrderSent'],
    ordersReceived: [type: mongoose.Schema.Types.ObjectId, ref: 'OrderReceived'],
);

你的删除函数应该包含如下内容:

Customer.findById(req.params.id)
    .then(customer => 
        if(customer.ordersSent.length== 0&& customer.ordersReceived.length== 0)
            return true
        //if there was more than 0
        return false
    ).then(result => 
        if(result)
            return Customer.findByIdAndRemove(req.params.id)
        res.status(409).json(message: 'There are orders received or sent using the Customer. Customer could not be deleted.')
    ).then(customerDataJustInCase =>
        res.status(200).json(message: 'Customer deleted.')
    ).catch(err => 
        //your error handler
    )

或者你可以通过 try-catch 来使用它。

【讨论】:

【参考方案2】:

您可以使用 Promise.all 方法一次执行所有数据库查询,如下所示:

Promise.all([
  OrderReceived.count(customer: req.params.id),
  OrderSent.count('customer.customer': req.params.id)
])
  .then(([orderReceivedCount, orderSendCount]) => 
    if (orderReceivedCount < 1 && orderSendCount<1)  
      ...delete doc 
    
   ).catch(error => ...handleError)

【讨论】:

以上是关于如果通过 Mongoose 在 Mongodb 的另一个文档中存在引用,有啥更好的方法可以防止文档被删除?的主要内容,如果未能解决你的问题,请参考以下文章

使用 mongoose 通过 update 方法向 mongodb 中的现有文档添加新字段

使用 mongoose 通过 update 方法向 mongodb 中的现有文档添加新字段

MongoDB、Mongoose、外键、连接表

通过在 body、mongoose/mongodb 中提供文档来更新多个文档

我无法使用 Mongoose 在 MongoDB 中保存或查找文档

无法通过 express/mongoose/angularjs 从 Mongodb 访问数据