簡體   English   中英

使用Mongoose和Node.js在MongoDB中刪除一對多和多對多關系中的引用

[英]Removing references in one-to-many and many-to-many relationships in MongoDB using Mongoose and Node.js

我需要提到的是,我完全意識到MongoDB並不是關系數據庫。 但是,它支持引用其他文檔,因此支持某些功能imo。 無論如何,我有這種關系:一個公司has many部門,一個部門belongs to一個公司。

company.js

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var CompanySchema = new Schema({
    name: {
        type: String,
        unique: true,
        required: true
    },
    departments: [{
        type: Schema.Types.ObjectId,
        ref: 'Department'
    }],
    dateCreated: {
        type: Date,
        default: Date.now
    },
    dateUpdated: {
        type: Date,
        default: Date.now
    }
});

module.exports = mongoose.model('Company', CompanySchema);

department.js

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var DepartmentSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    company: {
        type: Schema.Types.ObjectId,
        ref: 'Company'
    },
    dateCreated: {
        type: Date,
        default: Date.now
    },
    dateUpdated: {
        type: Date,
        default: Date.now
    }
});

module.exports = mongoose.model('Department', DepartmentSchema);

現在,我正在編寫Node.js邏輯以使用API​​來處理此數據。 我知道如果創建一個新部門,則應添加對Company的引用,並應在此Company的Departments數組中創建其引用。 簡單。 但是,如果用戶更改部門的Company屬性怎么辦? 假設人力資源部門曾經屬於公司A,但是現在有用戶將其移至公司B? 我們需要從公司A的數組中刪除對該部門的引用,並將其推到公司B。這與我們要刪除部門的情況相同。 我們需要找到它所屬的公司並取消其關聯。 我的解決方案是在ATM上運行,但看起來很笨拙。

routes.js

var Department = require('../../models/department'),
    Company = require('../../models/company');

module.exports = function(express) {
    var router = express.Router();

    router.route('/')
        .get(function(req, res) {
            // ...
        })
        .post(function(req, res) {
            // ...
        });

    router.route('/:id')
        .get(function(req, res) {
            // ...
        })
        .put(function(req, res) {

            // First we need to find the department with the request parameter id
            Department.findOne({ _id: req.params.id }, function(err, data) {
                if (err) return res.send(err);
                var department = data;
                // department.name = req.body.name || department.name; Not relevant

                // If the company to which the department belongs is changed
                if (department.company != req.body.company._id) {

                    // We should find the previous company
                    Company.findOne({ _id: department.company }, function(err, data) {
                        if (err) return res.send(err);
                        var company = data;

                        // Loop through its departments
                        for (var i = 0; i < company.departments.length; i++) {
                            if (company.departments[i].equals(department._id)) {

                                // And splice this array to remove the outdated reference
                                company.departments.splice(i, 1);
                                break;
                            }
                        }
                        company.save(function(err) {
                            if (err) return res.send(err);
                        });
                    });

                    // Now we find this new company which now holds the department in question
                    // and add our department as a reference
                    Company.findOne({ _id: req.body.company._id }, function(err, data) {
                        if (err) return res.send(err);
                        var company = data;
                        company.departments.push(department._id);
                        company.save(function(err) {
                            if (err) return res.send(err);
                        });
                    });
                }

                // department.company = req.body.company._id || department.company; Not relevant
                // department.dateUpdated = undefined; Not relevant

                // And finally save the department
                department.save(function(err) {
                    if (err) return res.send(err);
                    return res.json({ success: true, message: 'Department updated successfully.' });
                });
            });
        })
        .delete(function(req, res) {

            // Since we only have id of the department being deleted, we need to find it first
            Department.findOne({ _id: req.params.id}, function(err, data) {
                if (err) return res.send(err);
                var department = data;

                // Now we know the company it belongs to and should dis-associate them
                // by removing the company's reference to this department
                Company.findOne({ _id: department.company }, function(err, data) {
                    if (err) return res.send(err);
                    var company = data;

                    // Again we loop through the company's departments array to remove the ref
                    for (var i = 0; i < company.departments.length; i++) {
                        if (company.departments[i].equals(department._id)) {
                            company.departments.splice(i, 1);
                            break;
                        }
                    }
                    company.save(function(err) {
                        if (err) return res.send(err);
                    });

                    // I guess it should be synchronously AFTER everything is done,
                    // since if it is done in parallel with Department.findOne(..)
                    // piece, the remove part can happen BEFORE the dep is found
                    Department.remove({ _id: req.params.id }, function(err, data) {
                        if (err) return res.send(err);
                        return res.json({ success: true, message: 'Department deleted successfully.' });
                    });
                });
            });
        });

    return router;
};

對於這種情況,是否有任何優雅的解決方案?

我看到您尚未掌握node.js異步本質的本質...例如,您在department.save之前有一條注釋,其中說:最后……很好,早期的邏輯可能仍會在那時候...我也強烈建議您避免使用回調方法,並學習如何使用Promise做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM