adityap
adityap

Reputation: 739

Mongodb 2.4 2dsphere queries very slow

I have converted my old collection using mongodb "2d" index to a collection having geojson specification "2dsphere" index. The problem is that the query is taking about 11 second to execute on collection of about 2 lac objects. Previously is was taking about 100 ms for query. My document is as follow.

{ "_id": ObjectId("4f9c2aa2d142b9882f02a3b3"), "geonameId": NumberInt(1106542), "name": "Chitungwiza", "feature code": "PPL", "country code": "ZW", "state": "Harare Province", "population": NumberInt(340360), "elevation": "", "timezone": "Africa\/Harare", "geolocation": { "type": "Point", "coordinates": { "0": 31.07555, "1": -18.01274 } } }

My explain query output is given below.

db.city_info.find({"geolocation":{'$near':{ '$geometry': { 'type':"Point",coordinates:[73,23] } }}}).explain()

{
"cursor" : "S2NearCursor",
"isMultiKey" : true,
"n" : 172980,
"nscannedObjects" : 172980,
"nscanned" : 1121804,
"nscannedObjectsAllPlans" : 172980,
"nscannedAllPlans" : 1121804,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 13,
"nChunkSkips" : 0,
"millis" : 13841,
"indexBounds" : {

},
"nscanned" : 1121804,
"matchTested" : NumberLong(191431),
"geoMatchTested" : NumberLong(191431),
"numShells" : NumberLong(373),
"keyGeoSkip" : NumberLong(930373),
"returnSkip" : NumberLong(933610),
"btreeDups" : NumberLong(0),
"inAnnulusTested" : NumberLong(191431),
"server" : "..."
}

Please let me know how can I correct the problem and reduce the query time.

Upvotes: 1

Views: 1610

Answers (2)

Johnny C
Johnny C

Reputation: 1847

The $near command does not require $maxDistance argument for "2dsphere" databases as you suggest. Adding $maxDistance just specified a range that reduced the number of query results to a manageable number. The reason for the difference in your experience changing from "2d" to "2dsphere" style indexes is that "2d" indexes impose a default limit of 100 if none is specified. As you can see, the default query plan for 2dsphere indexes does not impose such limit so the query is scanning the entire index ("nscannedObjects" : 172980). If you ran the same query on a "2d" index you would see "n" and "nscannedObjects" are only 100 which explains the cost discrepancy.

If all of your items were within the $maxDistance range (try it with $maxDistance 20M meters, for instance), you will see the query performance degrade back to where it was without it. In either case, it is very important to use limit() to tell the query plan to only scan the necessary results within the index to prevent runaways, especially with larger data sets.

Upvotes: 2

adityap
adityap

Reputation: 739

I have solved the problem. The $near command requires $maxDistance argument as specified here: http://docs.mongodb.org/manual/applications/2dsphere/ . As soon as I supplied $maxDistance, the query time reduced to less than 100 ms.

Upvotes: 0

Related Questions