How can I do a spatial search using the Azure Search .NET SDK? The question has been answered for the REST API here:
How can I do the exact same using the .NET client API?
To be more specific:
How do I need to define the according property on the Document class? How can I query documents where the property value lies within a defined circle (center, radius)?
Just made it work on my last try (as always, just after posting the question...)
Reference the Nuget package Microsoft.Spatial
Use GeographyPoint
as property type in class definition:
public class MyDocument
{
[IsFilterable, IsSortable]
public Microsoft.Spatial.GeographyPoint Location { get; set; }
}
Create a document like this:
var lat = ...; //Latitude
var lng = ...; //Longitude
var myDoc = new MyDocument();
myDoc.Location = GeographyPoint.Create(lat, lng);
// Upload to index
Query like this:
// center of circle to search in
var lat = ...;
var lng = ...;
// radius of circle to search in
var radius = ...;
// Make sure to use invariant culture to avoid using invalid decimal separators
var latString = lat.ToString(CultureInfo.InvariantCulture);
var lngString = lng.ToString(CultureInfo.InvariantCulture);
var radiusString = radius.ToString(CultureInfo.InvariantCulture);
var searchParams = new SearchParameters();
searchParams.Filter = $"geo.distance(location, geography'POINT({lngString} {latString})') lt {radius}";
var searchResults = index.Documents.Search<Expert>(keyword, searchParams);
var items = searchResults.Results.ToList();
Note that location
corresponds to the property name Location
and needs to be replaced accordingly if your property is named differently. To sort results by distance, also set OrderBy
-property of search parameters:
searchParams.OrderBy = new List<string> { $"geo.distance(location, geography'POINT({lngString} {latString})') asc" };
It took me a while to find out that when defining the point in the query:
geography'POINT({lngString} {latString})'
The parameter order is (Longitude, Latitude)
other than in most other conventions (i.e. Google maps API uses other way around).