Spatial search
RavenDB supports performing queries based on spatial coordinates. That is, searching for locations which are within a specified radius from an origin.
Let's assume we build a restaurant-finder application, and to that end we store restaurant entities using the following structure:
public class Restaurant
{
public string Name { get; set; }
public double Longitude { get; set; }
public double Latitude { get; set; }
public short Rating { get; set; }
}
To allow spatial searches we will need to define an index like so:
public class Restaurants_ByRatingAndLocation : AbstractIndexCreationTask<Restaurant>
{
public Restaurants_ByRatingAndLocation()
{
Map = restaurants => from r in restaurants
select new {r.Rating, _ = SpatialIndex.Generate(r.Latitude, r.Longitude)};
}
}
The key part is the call to SpatialIndex.Generate()
. The field name assigned to it will be ignored, so we recommend using the underscore letter to mark it, which is a convention used to denote an unimportant variable.
This index gives us the ability to make spatial searches, using the following code:
var matchingRestaurants =
session.Advanced.LuceneQuery<Restaurant>("Restaurants/ByRatingAndLocation")
.WhereGreaterThanOrEqual("Rating", 4)
.WithinRadiusOf(radius: 5, latitude: 38.9103000, longitude: -77.3942)
.ToList();
This will return all the restaurants within 5 miles radius with a rating of 4 or more.