sql >> Database teknologi >  >> NoSQL >> MongoDB

Hvordan fjerner man objekt under hensyntagen til referencer i Mongoose Node.js?

Du skal indlejre dine opkald for at fjerne produkt-id'et fra den anden model. For eksempel i dit opkald om at fjerne produktet fra Produkt indsamling, kan du også foretage et andet opkald for at fjerne referenten fra Partner model inden for resultaterne tilbagekald. Fjernelse af produktet som standard vil fjerne dets referencer til Kampagnen Model.

Følgende kode viser intuitionen ovenfor:

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

For at fjerne de tilknyttede kampagner, skal du muligvis have en ekstra fjernoperation, der tager det tilknyttede kampagne-id fra et givet produkt-id. Overvej følgende beskidte hack, som potentielt kan give dig en enkeltbillet til callbackhell hvis du ikke er forsigtig med tilbagekaldsindlejringen:

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

Selvom det virker, kan ovenstående potentielle faldgrube undgås ved at bruge async/await eller async bibliotek. Men for det første for at give dig en bedre forståelse af brugen af ​​flere tilbagekald med async modul, lad os illustrere dette med et eksempel fra Seven Ting du bør stoppe med at gøre med Node.js af flere operationer med tilbagekald for at finde en overordnet enhed, og find derefter underordnede enheder, der tilhører overordnet:

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

Med async/wait vil dine opkald blive omstruktureret struktureret 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 async-modulet kan du enten bruge seriemetoden til at adressere brugen af ​​tilbagekald til indlejringskode for flere metoder, hvilket kan resultere 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 vandfaldet :

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 tilbage til din kode, ved at bruge den asynkrone vandfaldsmetode, kan du derefter omstrukturere din kode til

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. Pymongo-fejl for ArrayFilters til at opdatere flere underdokumenter

  2. Sådan konverteres streng til objectId i LocalField for $lookup Mongodb

  3. Hvorfor tager mongodump ikke backup af indekser?

  4. MongoDB begrænsede samling og monotisk stigende indeks