Elasticsearch 获取不同排序顺序的距离
Elasticsearch getting distance with different sort order
背景:
我们有以下要求:
- Data matching keyword should be returned.
- Data has longitude and latitude fields, result should be near specified lat long.
- Returned result should contain distance field, which specified distance between given lat long and lat long contained in data.
- Data should be sorted accouding to MultiMatch score.
阅读此 link 中的教程 Spatial Search ElasticSearch tutorial 我在 C# 中构建了以下查询。
var res = await _elasticClient
.SearchAsync<Results>(
s =>
s.Type("Data")
.Skip(skip)
.Take(limit)
.SortGeoDistance(es =>
es.Ascending().OnField("Coordinates").Unit(GeoUnit.Kilometers).PinTo(lat,lng))
.Query(
q1 =>
q1.Filtered(
f1 =>
f1.Query(q2 => q2.MultiMatch(mm => mm.OnFields(MultiMatchFieldsArray)
.Query(keyword)
.Type(TextQueryType.MostFields)))
.Filter(f2 => f2.GeoDistance("Coordinates",gf => gf.Distance(10,GeoUnit.Kilometers)
.Location(lat,lng))))));
根据教程,我必须使用 SortGeoDistance 方法来获取结果中的距离。使用 SortGeoDistance 将根据距离对结果进行排序,但需要根据 MultiMatch 分数对结果进行排序。
下面的 Whosebug answer 展示了如何在不使用排序的情况下获取距离。
下面是 C# 等效的答案。
var esSearch = await _elasticClient
.SearchAsync<Results>(
s =>
s.Type("Data")
.Skip(skip)
.Take(limit)
.Fields("_source")
.ScriptFields(sf => sf.Add("Distance", des => des.Params(param => param.Add("lat", lat).Add("lon", lng)).Script("doc[\u0027Coordinates\u0027].arcDistanceWithDefault(lat,lon,-1)")))
.Query(
q1 =>
q1.Filtered(
f1 =>
f1.Query(q2 => q2.MultiMatch(mm => mm.OnFields(MultiMatchFields)
.Query(keyword)
.Type(TextQueryType.MostFields)))
.Filter(f2 => f2.GeoDistance("Coordinates",gf => gf.Distance(10,GeoUnit.Kilometers)
.Location(lat,lng))))));
背景:
我们有以下要求:
- Data matching keyword should be returned.
- Data has longitude and latitude fields, result should be near specified lat long.
- Returned result should contain distance field, which specified distance between given lat long and lat long contained in data.
- Data should be sorted accouding to MultiMatch score.
阅读此 link 中的教程 Spatial Search ElasticSearch tutorial 我在 C# 中构建了以下查询。
var res = await _elasticClient
.SearchAsync<Results>(
s =>
s.Type("Data")
.Skip(skip)
.Take(limit)
.SortGeoDistance(es =>
es.Ascending().OnField("Coordinates").Unit(GeoUnit.Kilometers).PinTo(lat,lng))
.Query(
q1 =>
q1.Filtered(
f1 =>
f1.Query(q2 => q2.MultiMatch(mm => mm.OnFields(MultiMatchFieldsArray)
.Query(keyword)
.Type(TextQueryType.MostFields)))
.Filter(f2 => f2.GeoDistance("Coordinates",gf => gf.Distance(10,GeoUnit.Kilometers)
.Location(lat,lng))))));
根据教程,我必须使用 SortGeoDistance 方法来获取结果中的距离。使用 SortGeoDistance 将根据距离对结果进行排序,但需要根据 MultiMatch 分数对结果进行排序。
下面的 Whosebug answer 展示了如何在不使用排序的情况下获取距离。
下面是 C# 等效的答案。
var esSearch = await _elasticClient
.SearchAsync<Results>(
s =>
s.Type("Data")
.Skip(skip)
.Take(limit)
.Fields("_source")
.ScriptFields(sf => sf.Add("Distance", des => des.Params(param => param.Add("lat", lat).Add("lon", lng)).Script("doc[\u0027Coordinates\u0027].arcDistanceWithDefault(lat,lon,-1)")))
.Query(
q1 =>
q1.Filtered(
f1 =>
f1.Query(q2 => q2.MultiMatch(mm => mm.OnFields(MultiMatchFields)
.Query(keyword)
.Type(TextQueryType.MostFields)))
.Filter(f2 => f2.GeoDistance("Coordinates",gf => gf.Distance(10,GeoUnit.Kilometers)
.Location(lat,lng))))));