2016-04-16 12 views
2

私は、最も近い10個のオブジェクトを受け取る機能を持つプログラムを実装しています。私がElasticSearchを使用するデータベースとして、私のモデルはこのように見えます。 C#弾性検索でジオバランスを計算する(ネスト2)

[Nest.ElasticsearchType(Name = "eventelastic", IdProperty = "Id")] 
public class EventElastic:BaseElastic 
{ 
    [Nest.String] 
    public string EventName { get; set; } 
    [Nest.Date] 
    public DateTime CreateTime { get; set; } 
    [Nest.String] 
    public string Country { get; set; } 
    [Nest.String] 
    public string City { get; set; } 
    [Nest.String] 
    public string Place { get; set; } 
    [Nest.Boolean] 
    public bool IsPrivate { get; set; } 
    [Nest.Boolean] 
    public bool IsSponsored { get; set; } 
    [Nest.String] 
    public string ImageWeb { get; set; } 
    [Nest.Number] 
    public int MaxPersons { get; set; } 
    [Nest.GeoPoint] 
    public LocationModel Location { get; set; } 


} 

[Nest.ElasticsearchType(Name = "location", IdProperty = "Id")] 
public class LocationModel 
{ 
    public LocationModel(double lon, double lat) 
    { 
     Lon = lon; 
     Lat = lat; 
    } 

    public double Lon { get; set; } 

    public double Lat { get; set; } 
} 

私はこの

connection.CreateIndex("index", s => s.Mappings(f => f.Map<EventElastic>(m => m.AutoMap().Properties(p=> p.GeoPoint(g => g.Name(n => n.Location)))))); 

のようなインデックスを作成したと私は、モデルのすべての値が設定されている。この

var response = connection.IndexAsync<EventElastic>(model, idx => idx.Index("index")); 
      response.ContinueWith(t => 
      { 
       if (!t.Result.IsValid) 
       { 
        log.Error(t.Result.ServerError.Error.Reason); 
       } 
      }); 

のような新しいドキュメントを挿入し、それは問題なく動作します。

しかし、今私は10kmの範囲で最も近い10を取得したいと思います。 私はこの

var geoResult = connection.Search<EventElastic>(s => s.From(0).Size(10) 
      .Query(query => query.Bool(b => b.Filter(filter => filter 
        .GeoDistance(geo => geo 
         .Field(f => f.Location) //<- this 
         .Distance("10km").Location(lon, lat) 
         .DistanceType(GeoDistanceType.SloppyArc) 
         )) 
       ) 
      ) 
     ); 

のようにこれを照会するが、それは任意の文書を返すdoesntのが、私は万キロまでの距離値を設定している場合、それはドキュメントを返します。

iがモデルで使用されるデータである: LAT:47.4595248 LON:9.6385962

iは、検索に使用場所: LAT:47.4640298 LON:9.6389685

それらの場所は100メートルであります互いに離れている。 誰かが私のコードで間違いを見つけるのを助けることができますか? elasticsearchサーバーから計算された距離を得ることは可能ですか?

ところで:私は、デフォルトのインデックス

var settings = new ConnectionSettings(pool).DefaultIndex("index"); 

編集 を設定しています、私は間違いを見つけた:

var geoResult = connection.Search<EventElastic>(s => s.From(0).Size(10) 
     .Query(query => query.Bool(b => b.Filter(filter => filter 
       .GeoDistance(geo => geo 
        .Field(f => f.Location) 
        .Distance("10km").Location(lat, lon) //wrong parameter 
        .DistanceType(GeoDistanceType.SloppyArc) 
        )) 
      ) 
     ) 
    ); 

私は緯度と経度の位置を変更しなければなりませんでした。

しかし、私は計算された距離を取得しない、誰かが私は距離を得ることができるか知っていますか?

よろしく

+0

あなたはelasticsearchレスポンスで距離を取得しますか? – Rob

+0

はい、elasticsearchが私に5つの結果を返す場合、私はそれらを距離でソートして、距離をユーザに表示します。 –

答えて

0

あなたの文書にDistanceを追加し、この値を更新するクエリでsctipt fieldsを使用することができます。

var geoResult = client.Search<EventElastic>(s => s.From(0).Size(10) 
    .ScriptFields(sf => sf 
     .ScriptField("distance", descriptor => descriptor 
      .Inline("doc[\u0027location\u0027].distanceInKm(lat,lon)") 
      .Lang("groovy") 
      .Params(f => f.Add("lat", lat).Add("lon", lon)))) 
    .Query(query => query.Bool(b => b.Filter(filter => filter 
     .GeoDistance(geo => geo 
      .Field(f => f.Location) 
      .Distance("10km").Location(lat, lon) 
      .DistanceType(GeoDistanceType.SloppyArc) 
     )) 
     ) 
    ) 
    .Sort(sort => sort 
     .GeoDistance(g => g 
      .Field(f => f.Location) 
      .Order(SortOrder.Ascending) 
      .PinTo(new GeoLocation(1.5, 1)) 
      .DistanceType(GeoDistanceType.SloppyArc))) 
    ); 


public class EventElastic 
{ 
    .. 
    public double Distance {get;set;} 
} 

elasticsearchからの応答:

{ 
    "took": 3, 
    "timed_out": false, 
    "_shards": { 
     "total": 5, 
     "successful": 5, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 2, 
     "max_score": null, 
     "hits": [ 
     { 
      "_index": "my_index", 
      "_type": "data", 
      "_id": "1", 
      "_score": null, 
      "fields": { 
       "distance": [ 
        55.65975203179589 
       ] 
      }, 
      "sort": [ 
       55659.66677843493 
      ] 
     }, 
     { 
      "_index": "my_index", 
      "_type": "data", 
      "_id": "2", 
      "_score": null, 
      "fields": { 
       "distance": [ 
        124.45896068602408 
       ] 
      }, 
      "sort": [ 
       124411.81715215484 
      ] 
     } 
     ] 
    } 
} 

はそれがお役に立てば幸いです。

+0

Thx「ソート」が必要なものでした。私にとってはScriptFieldsがなくても動作しますが、ScriptFieldsは何か改善していますか?取得する値はわずかです。 "fields":{ "distance":[ 55。65975203179589 ] }、 "sort":[ 55659.66677843493 ] –