Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use $hint in MongoDB aggregation query?

I am using mongo v3.0.1 on a ubuntu machine. And I have a collection of 300million rows. I have created two indexes based on my query preference.

When I am trying to run aggregation with explain, It is taking the inefficient index, and that is why it's taking 20-25 secs more time. Is there any way to put $hint, so that my aggregation query use the appropriate index.

$match is in my first pipeline stage. I have two indexes:

  1. "Host_-1_SiteType_-1"

  2. "VisitTime_-1_AccountId_-1_Host_-1_SiteType_-1_Extension_-1_LifeTime_-1"

and my $match pipeline is like :

{ "$match" : {
    "AccountId": accID, 
    "VisitTime": { "$lte" : today, "$gte" : last365Days },
    "$or": [
        { "$and": [
            { "Extension":{ "$in": ["chrome_0","firefox_0"] }},
            { "LifeTime": 0 }
        ]},
        {  "LifeTime": { "$gt": 1000 }}
    ],
    "Host": { "$ne": "localhost" },
    "SiteType" : { "$exists": true },
}

and it is using first index, instead of second index. and the time taken by the first index in 50 secs where as using second index only it is taking only 18 secs.

Here is my one of the document sample:

{ 
    "_id" : "2bc1143c-07e4-4c37-a020-a7485b2802a3", 
    "CreatedDate" : ISODate("2015-07-22T04:05:06.802+0000"), 
    "UpdatedDate" : ISODate("2015-07-22T05:28:26.469+0000"), 
    "AccountId" : accID, 
    "Url" : "http://www.test.com/test.html", 
    "Host" : "test.com", 
    "VisitTime" : ISODate("2014-08-12T18:08:25.813+0000"), 
    "LifeTime" : 789546.01, 
    "Status" : "closed", 
    "LocalTime" : ISODate("2014-08-12T18:08:25.813+0000"), 
    "DeviceId" : "123456789", 
    "Extension" : "firefox_0", 
    "SubSiteType" : "TestSubSite", 
    "SiteType" : "TestSite", 
    "Flag" : "1"
}

and here is my aggregation explanation:

{
    "stages" : [
        {
            "$cursor" : {
                "query" : {
                    "AccountId" : "accID",
                    "VisitTime" : {
                        "$lte" : "2015-07-25T18:30:00Z",
                        "$gte" : "2014-07-25T18:30:00Z"
                    },
                    "Host" : {
                        "$ne" : "localhost"
                    },
                    "SiteType" : {
                        "$exists" : true
                    },
                    "$or" : [
                        {
                            "$and" : [
                                {
                                    "Extension" : {
                                        "$in" : [
                                            "chrome_0",
                                            "firefox_0"
                                        ]
                                    }
                                },
                                {
                                    "LifeTime" : 0
                                }
                            ]
                        },
                        {
                            "LifeTime" : {
                                "$gt" : 1000
                            }
                        }
                    ]
                },
                "fields" : {
                    "Host" : 1,
                    "_id" : 0
                },
                "queryPlanner" : {
                    "plannerVersion" : 1,
                    "namespace" : "Test",
                    "indexFilterSet" : false,
                    "parsedQuery" : {
                        "$and" : [
                            {
                                "$or" : [
                                    {
                                        "$and" : [
                                            {
                                                "LifeTime" : {
                                                    "$eq" : 0
                                                }
                                            },
                                            {
                                                "Extension" : {
                                                    "$in" : [
                                                        "chrome_0",
                                                        "firefox_0"
                                                    ]
                                                }
                                            }
                                        ]
                                    },
                                    {
                                        "LifeTime" : {
                                            "$gt" : 1000
                                        }
                                    }
                                ]
                            },
                            {
                                "$not" : {
                                    "Host" : {
                                        "$eq" : "localhost"
                                    }
                                }
                            },
                            {
                                "VisitTime" : {
                                    "$lte" : "2015-07-25T18:30:00Z"
                                }
                            },
                            {
                                "AccountId" : {
                                    "$eq" : "accID"
                                }
                            },
                            {
                                "VisitTime" :"2014-07-25T18:30:00Z"

                            },
                            {
                                "SiteType" : {
                                    "$exists" : true
                                }
                            }
                        ]
                    },
                    "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                            "$and" : [
                                {
                                    "SiteType" : {
                                        "$exists" : true
                                    }
                                },
                                {
                                    "$or" : [
                                        {
                                            "$and" : [
                                                {
                                                    "LifeTime" : {
                                                        "$eq" : 0
                                                    }
                                                },
                                                {
                                                    "Extension" : {
                                                        "$in" : [
                                                            "chrome_0",
                                                            "firefox_0"
                                                        ]
                                                    }
                                                }
                                            ]
                                        },
                                        {
                                            "LifeTime" : {
                                                "$gt" : 1000
                                            }
                                        }
                                    ]
                                },
                                {
                                    "VisitTime" : {
                                        "$lte" : "2015-07-25T18:30:00Z"
                                    }
                                },
                                {
                                    "AccountId" : {
                                        "$eq" : "accID"
                                    }
                                },
                                {
                                    "VisitTime" : {
                                        "$gte" : "2014-07-25T18:30:00Z"
                                    }
                                }
                            ]
                        },
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "Host" : -1,
                                "SiteType" : -1
                            },
                            "indexName" : "Host_-1_SiteType_-1",
                            "isMultiKey" : false,
                            "direction" : "forward",
                            "indexBounds" : {
                                "Host" : [
                                    "[MaxKey, \"localhost\")",
                                    "(\"localhost\", MinKey]"
                                ],
                                "SiteType" : [
                                    "[MaxKey, MinKey]"
                                ]
                            }
                        }
                    },
                    "rejectedPlans" : [
                        {
                            "stage" : "FETCH",
                            "filter" : {
                                "$and" : [
                                    {
                                        "SiteType" : {
                                            "$exists" : true
                                        }
                                    },
                                    {
                                        "$or" : [
                                            {
                                                "$and" : [
                                                    {
                                                        "LifeTime" : {
                                                            "$eq" : 0
                                                        }
                                                    },
                                                    {
                                                        "Extension" : {
                                                            "$in" : [
                                                                "chrome_0",
                                                                "firefox_0"
                                                            ]
                                                        }
                                                    }
                                                ]
                                            },
                                            {
                                                "LifeTime" : {
                                                    "$gt" : 1000
                                                }
                                            }
                                        ]
                                    }
                                ]
                            },
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                    "VisitTime" : -1,
                                    "AccountId" : -1,
                                    "Host" : -1,
                                    "SiteType" : -1,
                                    "Extension" : -1,
                                    "LifeTime" : -1
                                },
                                "indexName" : "VisitTime_-1_AccountId_-1_Host_-1_SiteType_-1_Extension_-1_LifeTime_-1",
                                "isMultiKey" : false,
                                "direction" : "forward",
                                "indexBounds" : {
                                    "VisitTime" : [
                                        "[new Date(1437849000000), new Date(1406313000000)]"
                                    ],
                                    "AccountId" : [
                                        "[\"accID\", \"accID\"]"
                                    ],
                                    "Host" : [
                                        "[MaxKey, \"localhost\")",
                                        "(\"localhost\", MinKey]"
                                    ],
                                    "SiteType" : [
                                        "[MaxKey, MinKey]"
                                    ],
                                    "Extension" : [
                                        "[MaxKey, MinKey]"
                                    ],
                                    "LifeTime" : [
                                        "[MaxKey, MinKey]"
                                    ]
                                }
                            }
                        }
                    ]
                }
            }
        },
        {
            "$group" : {
                "_id" : "$Host",
                "Count" : {
                    "$sum" : {
                        "$const" : 1
                    }
                }
            }
        },
        {
            "$sort" : {
                "sortKey" : {
                    "Count" : -1
                },
                "limit" : 5
            }
        },
        {
            "$project" : {
                "_id" : false,
                "Host" : "$_id",
                "TotalVisit" : "$Count"
            }
        }
    ],
    "ok" : 1
}
like image 870
Ankit Sarkar Avatar asked Jul 26 '15 05:07

Ankit Sarkar


People also ask

Can we use $and in aggregate MongoDB?

You can use $and with aggregation but you don't have to write it, and is implicit using different filters, in fact you can pipe those filters in case one of them needs a different solution.

How can you group by a particular value in MongoDB?

We can group by single as well as multiple field from the collection, we can use $group operator in MongoDB to group fields from the collection and returns the new document as result. We are using $avg, $sum, $max, $min, $push, $last, $first and $addToSet operator with group by in MongoDB.

Can we use count with aggregate function in MongoDB?

MongoDB $count AggregationThe MongoDB $count operator allows us to pass a document to the next phase of the aggregation pipeline that contains a count of the documents. There a couple of important things to note about this syntax: First, we invoke the $count operator and then specify the string.


1 Answers

2019 answer

From MongoDB version 3.6

From the documentation, you can add hint with aggregation in the following manner:

db.collection.aggregate(pipeline, {hint: "index_name"})

If you want to see explain just add explain as you would without hint

like image 172
buddygyan Avatar answered Oct 19 '22 07:10

buddygyan