mongodb - performance - Mongodb query on all second level documents if any of sub document satisfy condition - answerstu - answerstu.com answerstu

performance - Mongodb query on all second level documents if any of sub document satisfy condition

I am trying to get default_billing from address book in following second level sub document

{ 
        "_id" : ObjectId("5a841ac387c7d70ad36f5ce2"), 
        "user_type" : "retail", 
        "first_name" : "Mayank", 
        "last_name" : "Garg", 
        "addressbook" : {
            "5a93d64187c7d71562433a22" : {
                "consignee_name" : "Jerry Day", 
                "first_name" : "Cole", 
                "last_name" : "Bean", 
                "mobile" : "33333333333333", 
                "street_address" : "", 
                "street_address2" : "", 
                "city" : "", 
                "zip_code" : "58694", 
                "select_country" : "India", 
                "default_billing" : true
            }, 
            "5a9400f887c7d70aac2908e2" : {
                "consignee_name" : "Jerry Day", 
                "first_name" : "Cole", 
                "last_name" : "Bean", 
                "mobile" : "33333333333333", 
                "street_address" : "", 
                "street_address2" : "", 
                "city" : "",  
                "select_state" : "Delhi", 
                "zip_code" : "78004", 
                "select_country" : "India"
            }
        }
    }

I tried this

db.collection.find( {
 addressbook: {
 $all: [ { "$elemMatch" : { default_billing: true } } ]
 }
 } )

1 Answer

  1. Oscar- Reply

    2019-11-13

    You can use $objectToArray to make the object array, apply a filter on the array and use $arrayToObject convert back the array to object. If no match found in a document, addressbook will be an empty object. We can add $match as next stage to remove those if needed.

    db.collection.aggregate([{
        $addFields: {
            addressbook: {
                $objectToArray: '$addressbook'
            }
        }
    }, {
        $addFields: {
            addressbook: {
                $filter: {
                    input: '$addressbook',
                    as: 'ab',
                    cond: {$eq: ['$$ab.v.default_billing', true]}
                }
            }
        }
    }, {
        $addFields: {
            addressbook: {
                $arrayToObject: '$addressbook'
            }
        }
    }]);
    

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>