2015-03-29 6 views
2

Я углубился в использование NEST для проекта на основе .Net, который будет использовать ElasticSearch, но то, что продолжает или меня озадачивает, заключается в том, что запросы GeoDistance никогда не возвращали никаких результатов.Гнездо (Geo) Долговечность местоположения всегда 0?

При отладке ответов на простой запрос «*» и поиске документов. Результат поиска, все экземпляры документов имеют значение долготы 0.0 - Широта, однако, является правильной.

Это ES-сервер с голой костью, как свежий, как он получает (загружается и запускается), ничего (повторно) настроено. То же самое для одного, размещенного в FacetFlow.

Что касается версий, то они 1.4.3 для Elasticsearch.Net, а также NEST, ElasticSearch - это версия 1.4.4.

Есть ли что-то, что мне не хватает здесь или точнее - чего я здесь не хватает?

Пример кода выглядит это ( класс GeoLocation используется ниже является Nest.GeoLocation один):

using System; 
using System.Linq; 
using Nest; 

namespace NestPlayground 
{ 
    public class Post 
    { 
     public Guid Id { get; set; } 
     public string User { get; set; } 
     public DateTime CreatedAt { get; set; } 
     public string Message { get; set; } 
     public GeoLocation Location { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var indexName = "sampleindex"; 

      var uri = new Uri("<elasticsearch url>"); 
      var settings = new ConnectionSettings(uri).SetDefaultIndex(indexName); 
      var client = new ElasticClient(settings); 

      client.DeleteIndex(indexName); 

      var post = new Post 
      { 
       Id = Guid.NewGuid(), 
       User = "Some User", 
       CreatedAt = DateTime.UtcNow, 
       Message = "Some Sample Message", 
       Location = new GeoLocation(37.809860, -122.476995) 
      }; 

      client.Index(post); 
      client.Refresh(); 

      // Execute a search using the connection from above. 

      var result = client.Search<Post>(s => s 
           .Index(indexName) 
           .Query(queryDescriptor => queryDescriptor.QueryString(queryStringQueryDescriptor => queryStringQueryDescriptor.Query("*"))) 
           //.Filter(filterDescriptor => filterDescriptor.GeoDistance(post1 => post1.Location, geoDistanceFilterDescriptor => geoDistanceFilterDescriptor 
           // .Distance(50, GeoUnit.Kilometers) 
           // .Location(Lat: 37.802774, Lon: -122.4478561) 
           // .Optimize(GeoOptimizeBBox.Indexed))) 
           ); 

      // this DOES return the just created/indexed document, but its .Longitude/result.Documents.First().Location.Longtitude property is always '0'?! 
     } 
    } 
} 
+0

Может вы размещаете класс геолокации, ES и версию Nest ? – Rob

+0

Привет @Rob - верная вещь .. см. Обновленное сообщение для версий (версий) и происхождения класса GeoLocation. –

ответ

2

1. Похоже GeoLocation типа устареть. Даже NEST tests используют класс CustomGeoLocation.

Так что ваш Post класс должен выглядеть следующим образом:

public class Post 
{ 
    public Guid Id { get; set; } 
    public string User { get; set; } 
    public DateTime CreatedAt { get; set; } 
    public string Message { get; set; } 
    [ElasticProperty(Type = FieldType.GeoPoint)] 
    public Location Location { get; set; } 
} 

public class Location 
{ 
    public Location(double lat, double lon) 
    { 
     Lat = lat; 
     Lon = lon; 
    } 

    public double Lat { get; set; } 
    public double Lon { get; set; } 
} 

2. Документация Geo Distance Filter говорит:

Фильтр требует типа geo_point быть установлен на соответствующем поля.

вот почему я установил Location тип FieldType.GeoPoint.

Не забудьте создать сопоставление для вашего индекса.

client.CreateIndex(
    descriptor => 
     descriptor.Index(indexName) 
      .AddMapping<Post>(
       m => m.Properties(p => p 
        .GeoPoint(mappingDescriptor => mappingDescriptor.Name(f => f.Location).IndexLatLon())))); 

Я включил lat_lon, потому что вы хотите использовать GeoOptimizeBBox.Indexed в вашем GeoDistanceFilter.

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

{ 
    "sampleindex" : { 
     "mappings" : { 
      "post" : { 
       "properties" : { 
        "createdAt" : { 
         "type" : "date", 
         "format" : "dateOptionalTime" 
        }, 
        "id" : { 
         "type" : "string" 
        }, 
        "location" : { 
         "type" : "geo_point", 
         "lat_lon" : true 
        }, 
        "message" : { 
         "type" : "string" 
        }, 
        "user" : { 
         "type" : "string" 
        } 
       } 
      } 
     } 
    } 
} 

3. Теперь этот запрос, наконец, работает

var result = client.Search<Post>(s => s 
    .Index(indexName) 
    .Query(
     queryDescriptor => queryDescriptor.QueryString(queryStringQueryDescriptor => queryStringQueryDescriptor.Query("*"))) 
    .Filter(
     filterDescriptor => 
      filterDescriptor.GeoDistance(post1 => post1.Location, geoDistanceFilterDescriptor => geoDistanceFilterDescriptor 
       .Distance(500, GeoUnit.Kilometers) 
       .Location(37.802774, -122.4478561) 
       .Optimize(GeoOptimizeBBox.Indexed))) 
    ); 

Надеется, что это помогает :)

+0

Отлично, спасибо Робу много, особенно за то, что нашли время, чтобы объяснить, что и зачем! :) Приветствия! –

 Смежные вопросы

  • Нет связанных вопросов^_^