实现步骤:
1、定义属性
[Serializable]
public class Coordinate
{
public double Lat { get; set; }
public double Lon { get; set; }
}
/// <summary>
/// 位置坐标
/// </summary>
[ElasticProperty(Type = FieldType.GeoPoint)]
public Coordinate location { get; set; }
/// <summary>
/// 返回字段,距离值,适用于地理位置检索和排序 2016-03-25
/// </summary>
public double distance { get; set; }
2、创建索引时,设置Mapping:
_clientES.CreateIndex(indexName, s => s.AddMapping<DTOCarInfoIndexField>(f => f.MapFromAttributes().Properties(p => p.GeoPoint(g => g.Name(n => n.location).IndexLatLon()).String(fullinfo => fullinfo.Name(n => n.fullinfo).Index(FieldIndexOption.Analyzed).Analyzer("ik").Store(false)).String(description => description.Name(n => n.statedescription).Index(FieldIndexOption.Analyzed).Analyzer("ik").Store(false))).AllField(af => af.Enabled(false))).NumberOfReplicas(0));
3、向ES写入数据时,给location属性赋值:
#region 车源坐标 2015-11-30
string[] arrValue = ConvertHelper.ToStringArray(value.ToString(), ',');
if (arrValue.Length == 2)
{
var point = new Coordinate();
point.Lat = 0.0;
point.Lon = 0.0;
double x = ConvertHelper.ToDouble(arrValue[0]);
double y = ConvertHelper.ToDouble(arrValue[1]);
if (x > 0 && y > 0)
{
point.Lat = x;
point.Lon = y;
}
prop.SetValue(obj, point, null);
}
#endregion
4、搜索过程中按照距离排序并返回距离值(单位:km)(Nest组件):
//构建排序对象
List<KeyValuePair<PropertyPathMarker, ISort>> oneSortList = new List<KeyValuePair<PropertyPathMarker, ISort>>();
SortOrder ordertype = SortOrder.Ascending;
GeoDistanceSort sort = new GeoDistanceSort();
sort.Field = "location";
sort.Order = ordertype;
sort.GeoUnit = GeoUnit.Kilometers;
sort.PinLocation = locationpoint;
oneSortList.Add(new KeyValuePair<PropertyPathMarker, ISort>("_geo_distance", sort));
//构建ES检索对象
string[] returnFields=new[]{"id","distance"};
var searchRequest = new SearchRequest();
searchRequest.From = 0;
searchRequest.Size = 20;
searchRequest.Sort = oneSortList;
//定义返回列属性
searchRequest.Fields = returnFields.Select(f => (PropertyPathMarker)f.ToLower()).ToList();
//添加其他检索条件
//searchRequest.Query = queryList[i];
//searchRequest.Filter = listFilter[i];
#region 地理检索,添加距离返回值字段
if (!string.IsNullOrEmpty(locationPoint) && returnFields.Contains("distance"))
{
var distancefield = new Dictionary<string, IScriptFilter>();
var tempfield = new ScriptFilter();
tempfield.Params = new Dictionary<string, object>();
tempfield.Params.Add("lat", 116.403951);
tempfield.Params.Add("lon", 39.915031);
tempfield.Script = "doc['location'].arcDistanceInKm(lat,lon)";
distancefield.Add("distance", tempfield);
searchRequest.ScriptFields = distancefield;
}
#endregion
//执行检索,获取返回值
var resultSearch = esClient.Search<T>(searchRequest);
foreach (var doc in sResponse.FieldSelections)
{
var id = doc.FieldValues<object[]>("id").ToList()[0];
var distancevalue = doc.FieldValues<object[]>("distance").ToList()[0];
}
5、搜索过程中按照距离排序并返回距离值(单位:km)(Linq方式)
ESClient.Instance_TaocheCar().GetElasticClient().Search<DTOCarInfoIndexField>(s => s.From(0).Size(200).Fields(arrField).Filter(filter => filter.Terms("userid", list)).ScriptFields(sf => sf.Add("distance", descriptor => descriptor.Params(p => p.Add("lat", lat).Add("lon", lon)).Script("doc['location'].arcDistanceInKm(lat,lon)"))).SortGeoDistance(sg => sg.OnField("location").PinTo(lat, lon).Unit(GeoUnit.Kilometers).Ascending()));