Optimizing MongoDB Queries

I have a collection with a subdocument of over 40K records. My general query takes about 300 seconds. I tried optimizing the same using join as well as multivalued indexing which completes after 180 seconds.

I still need a reduction in query execution time.

here is my collection:

{
    "_id" : ObjectId("545b32cc7e9b99112e7ddd97"),
    "grp_id" : 654,
    "user_id" : 2,
    "mod_on" : ISODate("2014-11-06T08:35:40.857Z"),
    "crtd_on" : ISODate("2014-11-06T08:35:24.791Z"),
    "uploadTp" : 0,
    "tp" : 1,
    "status" : 3,
    "id_url" : [
     {"mid":"xyz12793"},
     {"mid":"xyz12794"},
     {"mid":"xyz12795"},
     {"mid":"xyz12796"}
    ],
    "incl" : 1,
    "total_cnt" : 25,
    "succ_cnt" : 25,
    "fail_cnt" : 0
}

      

and next is my request

db.member_id_transactions.aggregate([ { '$match':
                           { id_url: { '$elemMatch': { mid: 'xyz12794' } } } },
                           { '$unwind': '$id_url' },
                           { '$match': { grp_id: 654, 'id_url.mid': 'xyz12794' } } ])

      

Has anyone faced the same problem?

here o / p for aggregate query with explain option

{
    "result" : [ 
        {
            "_id" : ObjectId("546342467e6d1f4951b56285"),
            "grp_id" : 685,
            "user_id" : 2,
            "mod_on" : ISODate("2014-11-12T11:24:01.336Z"),
            "crtd_on" : ISODate("2014-11-12T11:19:34.682Z"),
            "uploadTp" : 1,
            "tp" : 1,
            "status" : 3,
            "id_url" : [
            {"mid":"xyz12793"},
            {"mid":"xyz12794"},
            {"mid":"xyz12795"},
            {"mid":"xyz12796"}
            ],
            "incl" : 1,
            "__v" : 0,
            "total_cnt" : 21406,
            "succ_cnt" : 21402,
            "fail_cnt" : 4
        }
    ],
    "ok" : 1,
    "$gleStats" : {
        "lastOpTime" : Timestamp(0, 0),
        "electionId" : ObjectId("545c8d37ab9cc679383a1b1b")
    }
}

      

+3


source to share


1 answer


One way to reduce the number of filtered records is to include a field grp_id

in the first statement $match

.

db.member_id_transactions.aggregate([ 
{$match:{ "id_url.mid": 'xyz12794',"grp_id": 654 } },
{$unwind: "$id_url" },
{$match: { "id_url.mid": "xyz12794" } } 
])

      

See how it works now. Add grp_id

to index to get better response times.



The above aggregation query, while it works, is not needed . since you are not changing the document structure and you expect only one element in the array to match the filter condition, you can just use simple find

and project

.

db.member_id_transactions.find(
{ "id_url.mid": "xyz12794","grp_id": 654 },
{"_id":0,"grp_id":1,"id_url":{$elemMatch:{"mid":"xyz12794"}},
 "user_id":1,"mod_on":1,"crtd_on":1,"uploadTp":1,
 "tp":1,"status":1,"incl":1,"total_cnt":1,
 "succ_cnt":1,"fail_cnt":1
}
)

      

+3


source







All Articles