I faced a problem using NEST in my Web Api Project for sorting by GeoDistance. I have:
- server with Elasticsearch v5.1.1 (working good)
- simple .NET Web Api application with NEST v5.0.1 installed (basic CRUD and search operations are working good)
Yesterday I decided to implement sorting by GeoDistance, however all possible solutions I had led me to this exception in Search/Sort requests:
Invalid NEST response built from a unsuccessful low level call on POST: /activities/activity/_search Audit trail of this API call:
[1] BadResponse: Node: http://MY_SERVER_IP:9200/ Took: 00:00:00.3129217 ServerError: ServerError: 400Type: search_phase_execution_exception Reason: "all shards failed" CausedBy: "Type:
illegal_argument_exception Reason:
"failed to find mapper for [geoposition] for geo distance based sort""
OriginalException: System.Net.WebException: The remote server returned an error: (400) Bad Request. at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
Request:
at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func
2 endFunction, Action1 endAction, Task
1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Elasticsearch.Net.HttpConnection.d__9`1.MoveNext() in C:\Users\russ\source\elasticsearch-net-5.x\src\Elasticsearch.Net\Connection\HttpConnection.cs:line 199force it to be set on the response.>
Response:ConnectionSettings to force it to be set on the response.>
My Model:
[ElasticsearchType(IdProperty = nameof(Id), Name = "activity")]
public class Activity
{
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "title")]
public string Title { get; set; }
[JsonProperty(PropertyName = "description")]
public string Description { get; set; }
[GeoPoint(Name = "geoposition")]
public GeoLocation Geoposition { get; set; }
[Date(Name = "date_published")]
public DateTime DatePublished { get; set; }
}
My NEST client initialization:
var settings = new ConnectionSettings(_node)
.DefaultIndex(_defaultIndex)
.MapDefaultTypeIndices(m => m.Add(typeof(Activity), _defaultIndex));
ElasticClient _client = new ElasticClient(settings);
I tried two different mapping approaches, because I didn't really get how to do this in a new NEST client:
_client.Map<Activity>(m => m.AutoMap().Properties(p => p.GeoPoint(geo => geo.Name(n => n.Geoposition))));
_client.Map<Activity>(m => m.Properties(p => p.GeoPoint(geo => geo.Name(n => n.Geoposition))));
My current query (give me error described above):
var result = await _client.SearchAsync<Activity>(s => s.Index(_defaultIndex)
//I removed search query to analyze only sorting problem
.Sort(
ss =>
ss.Descending(p => p.DatePublished)
.GeoDistance(
g => g
.Field(p => p.Geoposition)
.DistanceType(GeoDistanceType.Plane)
.Unit(DistanceUnit.Kilometers)
.Order(SortOrder.Ascending)
.PinTo(pin))));
My mapping response from elasticsearch server:
{
"activities": {
"mappings": {
"activity": {
"properties": {
"date_published": {
"type": "date"
},
"description": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"geoposition": {
"properties": {
"lat": {
"type": "float"
},
"lon": {
"type": "float"
}
}
},
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
Can somebody help me to solve this problem? I can not understand why it's not working and why mapping is not working.