This content is archived. See latest version here

Last updated: Feb 23 2015

Geo search is search based on geographical coordinates and distances. For the server to recognize that a pair of numbers are coordinates, the fields need to be mapped as a geo point. 

However, through conventions on the server side and in the .NET API, mapping is not needed as long as geographical locations are exposed as instances of the GeoLocation class. So, to use geo search functionality, indexed objects should have either a GeoLocation type property or a custom mapping, such as an extension method that returns a GeoLocation.

After objects with locations are indexed, you can filter on them using an expression that invokes the Within and WithinDistanceFrom extension methods.

Finding documents within a certain distance from a location

Assume the following class.

C#
using EPiServer.Find;

public class Restaurant
{
    public string Name { get; set; }

    public GeoLocation Location { get; set; }
}

And you create and index three instances of it with locations in Stockholm:

var closeToSergelsTorg = new Restaurant()
    {
        Name = "City steakhouse",
        Location = new GeoLocation(59.33265, 18.06468)
    };

var atSlussen = new Restaurant()
{
    Name = "Vegetarian place",
    Location = new GeoLocation(59.32067, 18.07294)
};

var atSkanstull = new Restaurant()
{
    Name = "Food and beer inn",
    Location = new GeoLocation(59.30792, 18.07672)
};

client.Index(closeToSergelsTorg,
                atSlussen,
                atSkanstull);

The above example shows three restaurants, one close to Sergels torg in the center of Stockholm, and two in another part of Stockholm, Sdermalm. You can now find restaurants close to Sergels torg by searching for restaurant type and filtering out documents whose Location property is not within one kilometer of Sergels torg.

 

var sergelsTorg = new GeoLocation(59.33234, 18.06291);

var result = client.Search<Restaurant>()
    .Filter(x => x.Location.WithinDistanceFrom(sergelsTorg, 1.Kilometer()))
    .GetResult();

This produces a single hit, the restaurant close to Sergels torg.

You can also search for documents within a specific range of a location.

C#
result = client.Search<Restaurant>()
    .Filter(x => 
        x.Location.WithinDistanceFrom(
        sergelsTorg, 
        1.Kilometer(), 
        2.Kilometers()))
    .GetResult();

Note the use of the two extension methods Kilometer and Kilometers above. The WithinDistanceFrom method requires distances as either miles or kilometers, which is represented by the abstract GeoDistance type and its sub classes Kilometer and Miles. The extension methods above offer a convenient way to create instances of the Kilometer class, which is a sub class of GeoDistance. Similar extension methods exist for miles.

Finding documents with locations in an area

Using the Within method, you can search for documents within an area represented by at least three coordinates. For example, you have the following helper class with coordinates that describe Sdermalm in Stockholm (found using Google maps).

C#
using System.Collections.Generic;
using EPiServer.Find;

public class CoordinatesOf
{
    public static IEnumerable<GeoLocation> Sodermalm
    {
        get
        {
            yield return new GeoLocation(59.32194, 18.07148);
            yield return new GeoLocation(59.32154, 18.07483);
            yield return new GeoLocation(59.32045, 18.07457);
            yield return new GeoLocation(59.31607, 18.10727);
            yield return new GeoLocation(59.30718, 18.09792);
            yield return new GeoLocation(59.30350, 18.07989);
            yield return new GeoLocation(59.30284, 18.07105);
            yield return new GeoLocation(59.30827, 18.04925);
            yield return new GeoLocation(59.31015, 18.03955);
            yield return new GeoLocation(59.31598, 18.02582);
            yield return new GeoLocation(59.31830, 18.02599);
            yield return new GeoLocation(59.31927, 18.02745);
            yield return new GeoLocation(59.31979, 18.03140);
            yield return new GeoLocation(59.32154, 18.05097);
        }
    }
}

You can use the Within method to find restaurants in Sdermalm.

C#
result = client.Search<Restaurant>()
    .Filter(x =>
        x.Location.Within(CoordinatesOf.Sodermalm))
    .GetResult();

Sorting by geographical distance

To order search hits for GeoLocation fields by distance from a location, use the OrderBy and OrderByDescending methods. As an example, the below code orders search results by closeness to Sergels Torg in Stockholm.

C#
var sergelsTorg = new GeoLocation(59.33234, 18.06291);

var result = client.Search<Restaurant>()
    .OrderBy(x => x.Location).DistanceFrom(sergelsTorg)
    .GetResult();

Matching documents with no location are ordered last when using the OrderBy method, and first when using the OrderByDescending method.

Aggregations/facets

Apart from filtering and sorting by geographical coordinates/distance, you can also count how many documents/locations are within certain distances from a specific location using the GeoDistanceFacetFor method. See geographical distance facets.

Do you have feedback on this documentation? Send an email to documentation@episerver.com. For development-related questions and discussions, refer to our Forums on https://world.episerver.com/forum/