Tutorial: GeoSpatial Search In MongoDB The Easy Way!
Tags: mongodb, csharp, dotnet, tutorial
Published: 2020-01-16 10:50:32

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.
{% link /djnitehawk/tutorial-mongodb-with-c-the-easy-way-1g68 %}

## Define The Gallery Entity

```csharp
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

```csharp
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:
```csharp
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
```csharp
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:
```csharp
using MongoDB.Driver;
```

add another property to the `ArtGallery` entity like so:
```csharp
public double DistanceInMeters { get; set; }
```

query mongodb with the `IAggregateFluent` interface like so:
```csharp
var results = await DB.FluentGeoNear<ArtGallery>(
                          NearCoordinates: locEiffelTower,
                          DistanceField: g => g.DistanceInMeters,
                          MaxDistance: 20000)
                      .ToListAsync();
```

write to the console like so:
```csharp
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](https://mongodb-entities.com) of **MongoDB.Entities**. you can also check out the source code on github:

{% github dj-nitehawk/MongoDB.Entities %}