Sitecore-MongoDB Calculate Closest Distance

This is a short guide about how to configure your mongoDB in order to calculate the closest distance between two coordinates.

In this case I will use a 2d index because it works with two-dimensional plane, latitude and latitude, which are the properties I have in my model. If you need more information about this index go to mongoDB documentation.

First, you will need a Coordinate object that will contain the latitude and longitude:

public class Coordinate
{
	public double Longitude { get; set; }

	public double Latitude { get; set; }
}

after you created that object, you will need to add it inside your model:

[BsonIgnoreExtraElements]
public class MyLocation
{
	public ObjectId _id { get; set; }

	public Coordinate Coordinates { get; set; }
}

This is how it should look like when you add a new document in your collection:

MongoDBCoordinates

Before I explain how to perform a query to mongoDB, I would like to show you how to create programmatically a Geospatial Index that will let us calculate the closest distance.

private static void CreateGeoSpatialIndex()
{
	string connectionString = ConfigurationManager.ConnectionStrings[Settings.GetSetting("MyDatabase")];
	if (connectionString == null || string.IsNullOrWhiteSpace(connectionString.ConnectionString)) return;

	var mongoUrl = new MongoUrl(connectionString.ConnectionString);
	var server = (new MongoClient(connectionString.ConnectionString)).GetServer();
	var database = server.GetDatabase(mongoUrl.DatabaseName);
	if (database == null) return;
	
	var collection = database.GetCollection(Settings.GetSetting("MyCollection"));
	if (collection == null) return;
	
	collection.EnsureIndex(IndexKeys.GeoSpatial("Coordinates"));
}

Notice “MyDatabase” is the name of connection string defined in the App_Config/ConnectionStrings.config

<add name="MyDatabase" connectionString="mongodb://localhost/appdata" />

If you want to create the index directly in mongoDB you can read this tutorial.

Once you’ve created the index, you can query if it is present in your collection:

db.getCollection('MyCollection').getIndexes()

Now, we are ready to query the closest distance between two coordinates. Take a look at the code below and you will notice that I use  the Near operator. I will use MongoDB.Driver library to perform queries.

public IEnumerable<MyLocation> GetClosestLocations(double latitude, double longitude)
{
	var db = GetMyCollection();
	var divisionQueryList = new List<IMongoQuery>();
	
	var nearLocations = db.FindAs<MyLocation>(Query.And(Query<MyLocation>.Near(q => q.Coordinates, longitude, latitude)));
	return nearLocations;
}

private static MongoDbCollection GetLocationsCollection()
{
	var mongoDbDriver = MongoDbDriver.FromConnectionString(Settings.GetSetting("MyDatabase"));

	return mongoDbDriver[Settings.GetSetting("MyCollection")];
}

You can use .Take(int) to return a specified number of items.

That’s it for today. Hope this is helpful for you.

Happy Sitecoring 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s