MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Как да премахнете обект, като вземете предвид препратките в Mongoose Node.js?

Ще трябва да вложите обажданията си, за да премахнете идентификатора на продукта от другия модел. Например във вашето обаждане за премахване на продукта от Продукт колекция, можете също да направите друго обаждане, за да премахнете референтния файл от Партньора модел в рамките на обратното извикване на резултатите. Премахването на продукта по подразбиране ще премахне неговите препратки към Кампания Модел.

Следният код показва горната интуиция:

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

За да премахнете свързаните кампании, тогава може да се нуждаете от допълнителна операция за премахване, която взема идентификатора на свързаната кампания от даден идентификатор на продукт. Помислете за следния мръсен хак, който потенциално може да ви осигури еднопосочен билет до callback hell ако не внимавате с влагането на обратното извикване:

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

Въпреки че работи, горният потенциален капан може да бъде избегнат чрез използване на async/await или async библиотека. Но първо, за да ви дам по-добро разбиране на използването на множество обратни извиквания с async модул, нека илюстрираме това с пример от Seven Неща, които трябва да спрете да правите с Node.js на множество операции с обратни извиквания за намиране на родителски обект, след което намиране на дъщерни обекти, които принадлежат на родителя:

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

С async/await вашите повиквания ще бъдат преструктурирани, структурирани като

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

С модула async можете или да използвате метода series за справяне с използването на обратни извиквания за код за влагане на множество методи, което може да доведе до Адът за обратно извикване :

Поредица :

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

Или водопад :

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

Сега се връщаме към кода ви, използвайки метода на асинхронен каскад, след което можете да преструктурирате кода си до

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. препоръчителен начин за инсталиране на mongodb на еластично бобено стъбло

  2. Не може да се използва $multiply с Number

  3. как да игнорирате дублирани документи, когато използвате insertMany в библиотеката на mongodb php?

  4. дублиране на колекция в себе си

  5. Премахване на име на числова колекция