如何从 elasticsearch.net / NEST 获取 geo_point 字段的距离
Posted
技术标签:
【中文标题】如何从 elasticsearch.net / NEST 获取 geo_point 字段的距离【英文标题】:How to get distance from elasticsearch.net / NEST for a geo_point field 【发布时间】:2020-01-26 21:33:18 【问题描述】:我想在我的搜索请求中获取 geo_point 的距离..
我已经写了这个请求,它给了我最接近我的搜索参数的点。
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))))));
我尝试了很多在网上找到的代码,但我无法将其改编为我的代码.. 我只想让弹性搜索返回每个点的距离。
我在elasticsearch中的字段是这样的(简单字符串):
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
]
谢谢。
【问题讨论】:
可以分享索引映射GET http://localhost:9200/indexname_mapping
吗?
当我用 '.' 替换 ','对于纬度/经度,我有 100 个命中和文档,但它们是空的,属性为空:/
【参考方案1】:
您需要使用脚本字段返回距离
"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
;
【讨论】:
谢谢,我一整天都在尝试这样做,但出了点问题。 InlineScript 中的字段是我在 elasticsearch 中映射的字段的名称?对我来说这是“地理”对吗?纬度,经度是我的点搜索吗?我尝试将脚本字段集成到我的代码中,但它不起作用。 是字段是文档字段和纬度,经度是点搜索。你能确认地理字段的映射吗 同时确认字段映射类型应为 "以上是关于如何从 elasticsearch.net / NEST 获取 geo_point 字段的距离的主要内容,如果未能解决你的问题,请参考以下文章
NEST/Elasticsearch.Net 发送原始JSON请求(Post数据)
Elasticsearch.Net.UnexpectedElasticsearchClientException:在从 ES 获取数据期间