db.tablebusiness.find({ "LongitudeLatitude" : { "$within" : { "$centerSphere" : [[106.772835, -6.186753], 0.0089967464101566] } }, "indexContents" : { "$all" : ["warung"] }, "Prominent" : { "$gte" : 15 } }).limit(50).explain;
{
"cursor" : "GeoBrowse-circle",
"nscanned" : 50,
"nscannedObjects" : 50,
"n" : 50,
"millis" : 214,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"LongitudeLatitude" : [ ]
},
"keysChecked" : NumberLong(13215),
"lookedAt" : NumberLong(13215),
"matchesPerfd" : NumberLong(13215),
"objectsLoaded" : NumberLong(6674),
"pointsLoaded" : NumberLong(0)
}
The query search for businesses within a circle that contains certain character. Typical data looks like this
/* 4 */
{
"_id" : "made's-warung__-6.18_106.78",
"BuildingID" : null,
"Title" : "Made’s Warung",
"InBuildingAddress" : null,
"Building" : null,
"Street" : "Seminyak-Kuta",
"Districts" : [],
"City" : "Bali",
"Country" : "Indonesia",
"DistanceFromGoogleAddress" : 0.0,
"Checkin" : 0,
"Note" : null,
"PeopleCount" : 106,
"Prominent" : 106.0,
"CountViews" : 0,
"StreetAdditional" : null,
"LongitudeLatitude" : {
"Longitude" : 106.783746,
"Latitude" : -6.177905
},
"Rating" : {
"Stars" : 0.0,
"Weight" : 0.0
},
"CurrentlyWorkedURL" : null,
"Reviews" : [],
"ZIP" : null,
"Tags" : ["Asian Restaurant"],
"Phones" : [],
"Website" : null,
"Email" : null,
"Price" : null,
"openingHour" : null,
"Promotions" : [],
"SomethingWrong" : false,
"BizMenus" : [],
"Brochures" : [],
"Aliases" : [],
"indexContents" : ["asian", "sian", "ian", "an", "n", "restaura", "estauran", "staurant", "taurant", "aurant", "urant", "rant", "ant", "nt", "t", "made’s", "ade’s", "de’s", "e’s", "’s", "s", "warung", "arung", "rung", "ung", "ng", "g"]
}
Also look at this one:
db.tablebusiness.find({ "LongitudeLatitude" : { "$nearSphere" : [106.772835, -6.186753], "$maxDistance" : 0.044983732050783008 }, "Prominent" : { "$gte" : 15 }, "indexContents" : { "$all" : [/^aru/, /^asi/] } }).limit(50).explain();
{
"cursor" : "GeoSearchCursor",
"nscanned" : 50,
"nscannedObjects" : 50,
"n" : 50,
"millis" : 2977,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
>
What does it mean? Is indexes used? Which one?
Best Answer
Yes, an index is used in both cases, just with different operators. The key to determining whether a query has used an index or not is the
"cursor" :
field. If this saysBasicCursor
then no index was used (a table scan was performed). Otherwise an index was used.In your case you are using a "2d" geo index each time, in fact for
$nearsphere
and$within, $centersphere
to work, you must be using a geo index.As for the rest of the output, they are both returning 50 objects, the first is significantly faster. You can see the explanation of the various fields here:
http://www.mongodb.org/display/DOCS/Explain
You have not listed what indexes you have defined, but if you wanted to attempt to speed things up you can try adding a compound index. Remember a query in MongoDB can only use one index at a time and for the geo commands to work that must be a 2d/geo index, so if you have indexes on your other fields, they will not be used unless they are part of a compound index with your geo index. You should also note that the 2d index must currently be the first field in the compound index, per here:
http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-CompoundIndexes