sql >> データベース >  >> NoSQL >> MongoDB

Mongoose Node.jsの参照を考慮してオブジェクトを削除するにはどうすればよいですか?

    他のモデルから製品IDを削除するには、呼び出しをネストする必要があります。たとえば、 Productから製品を削除するための呼び出しで コレクションの場合は、別の呼び出しを行って Partnerから参照を削除することもできます。 結果コールバック内のモデル。デフォルトで製品を削除すると、キャンペーンへの参照が削除されます モデル。

    次のコードは、上記の直感を示しています。

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

    関連するキャンペーンを削除するには、特定の製品IDから関連するキャンペーンIDを取得する追加の削除操作が必要になる場合があります。 コールバック地獄 への片道チケットを獲得する可能性のある次の汚いハックを考えてみてください。 コールバックのネストに注意しない場合:

    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. Mongodbを起動できません

    2. 私のコレクションで2つのフィールドの組み合わせをユニークにする

    3. マングースにスキーマとモデルの両方があるのはなぜですか?

    4. MongoDB:スキーマを定義する方法は?