sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur tar man bort objekt med hänsyn till referenser i Mongoose Node.js?

Du skulle behöva kapsla dina samtal för att ta bort produkt-id:t från den andra modellen. Till exempel i ditt samtal om att ta bort produkten från Produkt samling, kan du också ringa ett annat samtal för att ta bort referensen från Partner modell inom resultatet callback. Om du tar bort produkten som standard tas dess referenser till Kampanjen bort Modell.

Följande kod visar intuitionen ovan:

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

För att ta bort de associerade kampanjerna kan du behöva en extra borttagningsåtgärd som tar in det associerade kampanj-id från ett givet produkt-id. Tänk på följande smutsiga hack som potentiellt kan ge dig en enkelbiljett till återuppringningshelvetet om du inte är försiktig med återuppringning:

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

Även om det fungerar, kan ovanstående potentiella fallgrop undvikas genom att använda async/await eller async bibliotek. Men först, för att ge dig en bättre förståelse för hur du använder flera återuppringningar med async modul, låt oss illustrera detta med ett exempel från Seven Saker du bör sluta göra med Node.js av flera operationer med återuppringningar för att hitta en överordnad enhet och sedan hitta underordnade enheter som tillhör den överordnade:

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

Med async/await omstruktureras dina samtal strukturerade som

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

Med asynkroniseringsmodulen kan du antingen använda seriemetoden för att adressera användningen av callbacks för kapslingskod för flera metoder, vilket kan resultera i Callback Hell :

Serie :

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

Eller vattenfallet :

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

Går nu tillbaka till din kod, med den asynkrona vattenfallsmetoden kan du sedan omstrukturera din kod till

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. Hur man tar bort overifierade användare med Mongoose och TTL

  2. Hur hittar man till mongodb till det sista objektet i en array?

  3. problem med att ställa in selleriuppgifter backend i Python

  4. Mongo 3.6 aggregeringssökning med flera villkor