I would like to get in my search request the distance for a geo_point..
I already write this request that gives me closest point to my searching param.
ConnectionSettings elasticSettings = new ConnectionSettings(new Uri("http://localhost:9200"));
ElasticClient client = new ElasticClient(elasticSettings);
var searchResults = client.Search<dynamic>(s => s.Index("index1,index2,index3").From(0).Size(10).Query(
q => q.Bool(
b => b.Must(
f => f.GeoDistance(
g => g.Distance(20, DistanceUnit.Kilometers).DistanceType(GeoDistanceType.Arc).Field("geo").Location(lat, lon))))));
I tried a lot of code found on the web but I can not adapt it for my code.. I just want that elasticsearch return me the distance foreach point.
My field in elasticsearch is like that (simple string):
geo 74.875,-179.875
and in another index test, is like that (structured) : the search doesn't works like this
geo {
"lat": 74.875,
"lon": -178.625
}
Is the first or second mapping can have an impact on the query ?
Here is my mapping for the index :
{
"index1": {
"aliases": {},
"mappings": {
"properties": {
"Date": { "type": "date" },
"Value": { "type": "text" },
"geo": { "type": "geo_point" }
}
},
"settings": {
"index": {
"refresh_interval": "1s",
"number_of_shards": "4",
"provided_name": "index1",
"creation_date": "1569420798736",
"number_of_replicas": "0",
"uuid": "jqc1RRhxSC2e5yJJX2lyzw",
"version": { "created": "7030199" }
}
}
} }
I integrate a scripfield in my query like that :
var searchResults = client.Search<dynamic>(s => s.Index("index").From(0).Size(100).ScriptFields(sf => sf.ScriptField("distance", d => d.Source("if(doc['geo'].size(){doc['geo'].arcDistance("+ lat+","+ lon + ")}"))).Query(
q => q.Bool(
b => b.Must(
f => f.GeoDistance(
g => g.Distance(20, DistanceUnit.Kilometers).DistanceType(GeoDistanceType.Arc).Field("geo").Location(lat, lon))))));
With this request, I have a "200 successfull" responses and it seems that I it returns me the distance but not the other field, and the 100 documents are null.
Valid NEST response built from a successful (200) low level call on
POST: /index1/_search?typed_keys=true
# Audit trail of this API call:
- [1] HealthyResponse: Node: http://localhost:9200/ Took:
00:00:01.0670113
# Request:
{"from":0,"query":{"bool":{"must":[{"geo_distance":
{"distance":"200km","distance_type":"arc","geo":
{"lat":57.123,"lon":-20.876}}}]}},"script_fields":{"distance":{"script":
{"source":"doc['geo'].arcDistance(57.123,-20.876)"}}},"size":100}
# Response:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 4,
"successful": 4,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1203,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "index1",
"_type": "_doc",
"_id": "121197",
"_score": 1.0,
"fields": { "distance": [ 198251.11868760435 ] }
},
{
"_index": "index1",
"_type": "_doc",
"_id": "121198",
"_score": 1.0,
"fields": { "distance": [ 197018.831847128 ] }
},
...98 more
]
}
}
Thank you.
You need to use script field to return distance
"script_fields":{
"distance":{
"script":"doc['latlng'].arcDistance(params.lat,params.lng)",
"params":{
"lat":<some value>,
"lng":<some value>
}
}
}
Nest
var scriptFields = new ScriptFields
{
{
"distance", new ScriptField {
Script = new InlineScript( "if(doc['"+field+"'].size() > 0) { doc['"+field+"'].arcDistance(params.lat,params.lon) }")
{
Params=new FluentDictionary<string, object>
{
{ "lat", latitude},
{ "lon", longitude}
}
}
}
}
};