Как получить расстояние отasticsearch.net / NEST для поля geo_point - PullRequest
0 голосов
/ 26 сентября 2019

Я хотел бы получить в моем поисковом запросе расстояние для географической точки ..

Я уже написал этот запрос, который дает мне самую близкую точку к моему поисковому параметру.

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Я пробовал много кода, найденного в сети, но я не могу адаптировать его для своего кода ... Я просто хочу, чтобыasticsearch возвращал мне точку foreach расстояния.

Мое поле вasticsearch такое (простая строка):

    geo 74.875,-179.875 

и в другом индексном тесте похожи (структурированы): поиск работает не так

geo {
"lat": 74.875,
"lon": -178.625
}

Может ли первое или второе отображение повлиять назапрос?

Вот мое отображение для индекса:

{
"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" }
  }
}

}}

Я интегрирую поле сценария в свой запрос следующим образом:

  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))))));

С этим запросом у меня есть "200 успешных" ответов, и кажется, что он возвращает мне расстояние, но не другое поле, и 100 документов равны нулю.

    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
    ]
  }
}

Спасибо.

1 Ответ

0 голосов
/ 26 сентября 2019

Вам необходимо использовать поле скрипта для возврата расстояния

"script_fields":{
     "distance":{
            "script":"doc['latlng'].arcDistance(params.lat,params.lng)",
            "params":{
                    "lat":<some value>,
                    "lng":<some value>
             }
      }
}

Гнездо

 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}
                           }
                       }
                   }
                }
            };
...