Problem Statement
Find all locations that are within a certain radius of a particular location.
Solution Approach
We will demonstrate this with pseudo-code.
Let us insert lots of location specific data in MongoDB.
We will search this very data later.
static Mongo m;
static DB db;
static DBCollection coll;
m = new Mongo("localhost");
db = m.getDB("mydb");
coll = db.getCollection("people");
coll.ensureIndex((DBObject) JSON.parse("{ 'loc' : '2d' }"));
Random rand = new Random();
long startTime = Calendar.getInstance().getTimeInMillis();
for (int i = 0; i < 100000; i++)
{
double lat = rand.nextDouble() * 180 - 90;
BigDecimal bd1 = new BigDecimal(lat).setScale(2,RoundingMode.HALF_EVEN);
lat = bd1.doubleValue();
if (lat = 90)
lat = lat - 0.5;
double lon = rand.nextDouble() * 360 - 180;
BigDecimal bd = new BigDecimal(lon).setScale(2, RoundingMode.HALF_EVEN);
lon = bd.doubleValue();
if (lon = 90)
lon = lon - 0.5;
// System.out.println("lon / lat = " + lon + " / " + lat);
// lat=1; lon=1;
coll.insert((DBObject) JSON.parse("{'loc' : [ " + lon + " , " + lat + " ]}"), WriteConcern.SAFE);
}
long timeTaken = Calendar.getInstance().getTimeInMillis() - startTime;
System.out.println("Total Time Taken to Insert (milliseconds): " + timeTaken);
Now we want to do a geo spatial search on the above inserted data.
i.e find all documents(rows) whose location is within a certain miles(radius) from a particular location(lat,lon):
There are several ways to do this search.
Lets look at them one by one.
//Using $nearSphere to find all locations that are within 1000 miles from location 78,10
static void searchWithNearSphere()
{
// 1 radian = 3959 miles (6371 km).
// So, 100 miles = 100/3959 = 0.0253 radians.
// So, 1000 miles = 1000/3959 = 0.253 radians.
System.out.println("searchWithNearSphere: Query to run: "
+ "{'$nearSphere' : [ 78 , 10 ] , '$maxDistance' : 0.253}");
long startTime = Calendar.getInstance().getTimeInMillis();
// Must use long/lat format, and not lat/long.
// Valid bounds for latitude is -90/90.
// Valid bounds for longitude is -180/180
DBCursor cur = coll.find(new BasicDBObject("loc", JSON.parse("{'$nearSphere' : [ 78 , 10 ] , '$maxDistance' : 0.253}"))).limit(100000);
long timeTaken = Calendar.getInstance().getTimeInMillis() - startTime;
System.out.println("Total Time Taken for 'searchWithNearSphere(milliseconds): " + timeTaken);
System.out.println("Total Documents Found: " + cur.count());
System.out.println("Total Documents Found: " + cur.length());
System.out.println("Total Documents Found: " + cur.size());
/*
* while (cur.hasNext()) { System.out.println(cur.next()); }
*
* System.out.println("Total Documents Found: " + cur.size());
*/
}
// Using geoNear command to find all locations that are within 1000 miles from location 78,10
static void searchWithGeoNear()
{
BasicDBObject cmd = new BasicDBObject();
cmd.put("geoNear", "people");
int coord[] = { 78, 10 };
cmd.put("near", coord);
cmd.put("num", 1000);
cmd.put("maxDistance", 0.253);
cmd.put("spherical", true);
long startTime = Calendar.getInstance().getTimeInMillis();
CommandResult r = db.command(cmd);
long timeTaken = Calendar.getInstance().getTimeInMillis() - startTime;
System.out.println("Total Time Taken for 'searchWithGeoNear(milliseconds): " + timeTaken);
System.out.println(r.ok());
System.out.println(r.getErrorMessage());
// System.out.println(r.toString());
// print(r);//Print all the returned data.
com.mongodb.BasicDBList resultsBasicDBList = (BasicDBList) r.get("results");
System.out.println("Total Results: " + resultsBasicDBList.size());
// System.out.println("Results: " + resultsBasicDBList); //This will
// print the value of 'results' key.
// print(resultsBasicDBList);//This will print individual values.
}
//The print function to print a DBObject:
public static void print(DBObject doc)
{
Set allKeys = doc.keySet();
Iterator it = allKeys.iterator();
while (it.hasNext())
{
Object o = it.next();
String temp = (String) o; // it.next();
// System.out.println("K CLASS: " + o);
// System.out.println("V CLASS: " + doc.get(temp).getClass());
System.out.print(temp + "-");
if (doc.get(temp) instanceof BasicDBObject)
{
System.out.println("\n");
print((DBObject) doc.get(temp));
}
else
{
System.out.println(doc.get(temp));
if (temp.toString().equalsIgnoreCase("loc"))
System.out.println("-------------");
}
}//end of while
}
// To clean up a collection completely
static void clean()
{
// clear records if any
DBCursor cur = coll.find();
while (cur.hasNext())
coll.remove(cur.next());
}
Thats It!
Recent Comments