MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Làm cách nào để xóa đối tượng có tính đến các tham chiếu trong Mongoose Node.js?

Bạn sẽ phải lồng các lệnh gọi của mình để xóa id sản phẩm khỏi mô hình khác. Ví dụ:trong cuộc gọi của bạn để xóa sản phẩm khỏi Sản phẩm bộ sưu tập, bạn cũng có thể thực hiện một cuộc gọi khác để xóa tham chiếu khỏi Đối tác mô hình trong cuộc gọi lại kết quả. Loại bỏ sản phẩm theo mặc định sẽ loại bỏ các tham chiếu của nó đối với Chiến dịch Người mẫu.

Đoạn mã sau cho thấy trực giác ở trên:

var campSchema = require('../model/camp-schema');

router.post('/removeProduct', function (req, res) {
    campSchema.Product.findOneAndRemove({ _id: req.body.productId }, function (err, response) {
        if (err) throw err;
        campSchema.Partner.update(
            { "products": req.body.productId },
            { "$pull": { "products": req.body.productId } },
            function (err, res){
                if (err) throw err;
                res.json(res);
            }
        );
    });
});

Để loại bỏ các chiến dịch được liên kết, bạn có thể cần thêm một thao tác xóa có trong id chiến dịch được liên kết với một id sản phẩm nhất định. Hãy xem xét vụ tấn công bẩn thỉu sau đây có thể có khả năng trao cho bạn vé một chiều đến địa ngục gọi lại nếu không cẩn thận với lồng gọi lại:

router.post('/removeProduct', function (req, res) {
    campSchema.Product.findOneAndRemove(
        { _id: req.body.productId }, 
        { new: true },
        function (err, product) {
            if (err) throw err;
            campSchema.Partner.update(
                { "products": req.body.productId },
                { "$pull": { "products": req.body.productId } },
                function (err, res){
                    if (err) throw err;
                    var campaignList = product.campaign
                    campSchema.Campaign.remove({ "_id": { "$in": campaignList } })
                                .exec(function (err, res){
                                    if (err) throw err;
                                    res.json(product);
                                })
                }
            );
        }
    );
});

Mặc dù nó hoạt động nhưng có thể tránh được cạm bẫy tiềm ẩn ở trên bằng cách sử dụng async / await hoặc async thư viện. Nhưng trước hết, để bạn hiểu rõ hơn về việc sử dụng nhiều lệnh gọi lại với async mô-đun, hãy minh họa điều này bằng một ví dụ từ Seven Những điều bạn nên ngừng làm với Node.js của nhiều hoạt động với các lệnh gọi lại để tìm một thực thể mẹ, sau đó tìm các thực thể con thuộc về chính:

methodA(function(a){
    methodB(function(b){
        methodC(function(c){
            methodD(function(d){
                // Final callback code        
            })
        })
    })
})

Với async / await, các cuộc gọi của bạn sẽ được cấu trúc lại thành

router.post('/removeProduct', async (req, res) => {
    try {
        const product = await campSchema.Product.findOneAndRemove(
            { _id: req.body.productId }, 
            { new: true }
        )

        await campSchema.Partner.update(
            { "products": req.body.productId },
            { "$pull": { "products": req.body.productId } }
        )

        await campSchema.Campaign.remove({ "_id": { "$in": product.campaign } })

        res.json(product)
    } catch(err) {
        throw err
    }
})

Với mô-đun không đồng bộ, bạn có thể sử dụng phương thức chuỗi để giải quyết việc sử dụng lệnh gọi lại cho mã lồng nhau của nhiều phương thức có thể dẫn đến Địa ngục gọi lại :

Chuỗi :

async.series([
    function(callback){
        // code a
        callback(null, 'a')
    },
    function(callback){
        // code b
        callback(null, 'b')
    },
    function(callback){
        // code c
        callback(null, 'c')
    },
    function(callback){
        // code d
        callback(null, 'd')
    }],
    // optional callback
    function(err, results){
        // results is ['a', 'b', 'c', 'd']
        // final callback code
    }
)

Hoặc thác nước :

async.waterfall([
    function(callback){
        // code a
        callback(null, 'a', 'b')
    },
    function(arg1, arg2, callback){
        // arg1 is equals 'a' and arg2 is 'b'
        // Code c
        callback(null, 'c')
    },
    function(arg1, callback){      
        // arg1 is 'c'
        // code d
        callback(null, 'd');
    }], function (err, result) {
        // result is 'd'    
    }
)

Bây giờ quay lại mã của bạn, sử dụng phương pháp thác nước không đồng bộ, sau đó, bạn có thể cấu trúc lại mã của mình thành

router.post('/removeProduct', function (req, res) {
    async.waterfall([
        function (callback) {
            // code a: Remove Product
            campSchema.Product.findOneAndRemove(
                { _id: req.body.productId }, 
                function (err, product) {
                    if (err) callback(err);
                    callback(null, product);
                }
            );
        },

        function (doc, callback) {
            // code b: Remove associated campaigns
            var campaignList = doc.campaign;
            campSchema.Campaign
                .remove({ "_id": { "$in": campaignList } })
                .exec(function (err, res) {
                if (err) callback(err);
                callback(null, doc);
            }
            );
        },

        function (doc, callback) {
            // code c: Remove related partner
            campSchema.Partner.update(
                { "products": doc._id },
                { "$pull": { "products": doc._id } },
                function (err, res) {
                    if (err) callback(err);
                    callback(null, doc);
                }
            );
        }
    ], function (err, result) {
        if (err) throw err;
        res.json(result);  // OUTPUT OK
    });
});



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Sử dụng ứng dụng Meteor trên iPad đã được triển khai tới máy chủ từ xa với Meteor-up (sự cố kết nối với mongodb)

  2. Kế thừa trong MongoDb:cách yêu cầu các phiên bản của kiểu đã xác định

  3. Trình xử lý nhập dữ liệu solr cho MongoDB

  4. Mongo có thể trả lại các tài liệu có các trường trống / thiếu ở cuối theo thứ tự asc không?

  5. cách thực thi lệnh quản trị mongo từ java