loading...
Cover image for Tutorial: GeoSpatial Search In MongoDB The Easy Way!

Tutorial: GeoSpatial Search In MongoDB The Easy Way!

djnitehawk profile image Đĵ ΝιΓΞΗΛψΚ Updated on ・3 min read

let's say we have a bunch of art galleries stored in mongodb located in paris and we want to retrieve only those that are within 20 kilometers of the eiffel tower.

mongodb makes it extremely easy if you store the entities properly tagged with their longitudes and latitudes.

Getting Started

if you haven't already, please see the introductory article mentioned below in order to get a new project setup before continuing with the rest of this article.

Define The Gallery Entity

public class ArtGallery : Entity
{
    public string Name { get; set; }
    public Coordinates2D Location { get; set; }
}

the Coordinates2D type is a special class supplied by the library to streamline the storage & retrieval of geographical data.

Create Some Entities

await new[]
{
    new ArtGallery {
        Name = "Galleria Le-Pari",
        Location = new Coordinates2D(48.8539241, 2.2913515)
    },
    new ArtGallery {
        Name = "Versailles House Of Art",
        Location = new Coordinates2D(48.796964, 2.137456)
    },
    new ArtGallery {
        Name = "Poissy Arts & Crafts",
        Location = new Coordinates2D(48.928860, 2.046889)
    }
}.SaveAsync();

we are setting the locations of these galleries by creating new instances of Coordinates2D class supplying the longitude and latitude to the constructor. finally the whole array is persisted to mongodb by calling the .SaveAsync() extension method which issues a bulk write command.

Create An Index

mongodb geospatial queries require an index to be created which can be easily done as follows:

await DB.Index<ArtGallery>()
        .Key(g => g.Location, KeyType.Geo2DSphere)
        .Option(o => o.Background = false)
        .CreateAsync();

we specify the index key as the Location property of the ArtGallery class and type of key as Geo2DSphere. also we are telling mongodb to build the index in the foreground with the .Option() method.

Do The Search

var locEiffelTower = new Coordinates2D(48.857908, 2.295243);

var results = await DB.Find<ArtGallery>()
                      .Match(g => g.Location, locEiffelTower, 20000)
                      .ExecuteAsync();

foreach (var gallery in results)
{
    Console.WriteLine(gallery.Name);
}

Console.Read();

first we define the search point, which in this case is the location/coordinates of the eiffel tower in paris.

then we issue a find command that has the following matching criteria/arguments:

  1. the property where coordinates are stored on the ArtGallery entity.
  2. the search point to base the matching on.
  3. how far away from the search point (in meters) - at maximum should matches be located in.

The End Result

after running the find command you will see the following output in the console window:

Galleria Le-Pari
Versailles House Of Art

notice that Poissy Arts & Crafts has been excluded. that is because it is located further than 20KMs from the eiffel tower.

Getting Distances Back

if you need to also retrieve how far away each gallery is from the eiffel tower, simply do the following:

add the following import:

using MongoDB.Driver;

add another property to the ArtGallery entity like so:

public double DistanceInMeters { get; set; }

query mongodb with the IAggregateFluent interface like so:

var results = await DB.FluentGeoNear<ArtGallery>(
                          NearCoordinates: locEiffelTower,
                          DistanceField: g => g.DistanceInMeters,
                          MaxDistance: 20000)
                      .ToListAsync();

write to the console like so:

foreach (var gallery in results)
{
    Console.WriteLine(
    $"{gallery.Name} - {(gallery.DistanceInMeters / 1000).ToString("00.00")} KM");
}

Next Steps...

if the above exercise has piqued your interest enough to discover how to easily get things done with mongodb using c#, please visit the official website of MongoDB.Entities. you can also check out the source code on github:

GitHub logo dj-nitehawk / MongoDB.Entities

A data access library for MongoDB with an elegant api, LINQ support and built-in entity relationship management

nuget nuget tests license

MongoDB.Entities

A light-weight .net standard library which simplifies access to mongodb by abstracting away the official .net mongodb driver and providing some additional features on top of it. The API is clean and intuitive resulting in less lines of code that is more human friendly than driver code.

More Info:

please visit the official website for detailed documentation:

https://mongodb-entities.com

Posted on by:

djnitehawk profile

Đĵ ΝιΓΞΗΛψΚ

@djnitehawk

Developer @ ChangeMon.com (Change Detection & Notification Service)

Discussion

pic
Editor guide
 

Hi, I implemented all the steps but the final result is Zero, I use the exact same coordinates that the example and I get zero results, do you know what can I be missing?

 

i just copy/pasted the above code into a new console project and it works fine. here's a gist if you wanna try again. the only thing i had to add was the connection initialization.