2013-04-19 12 views
16

Załóżmy, że mamy garść dokumentów w indeksie ElasticSearch. Każdy dokumenty ma wiele lokalizacji w tablicy coś takiego:ElasticSearch filtr odległości geograficznej z wieloma lokalizacjami w tablicy - możliwe?

{ 
    "name": "foobar", 
    "locations": [ 
    { 
     "lat": 40.708519, 
     "lon": -74.003212 
    }, 
    { 
     "lat": 39.752609, 
     "lon": -104.998100 
    }, 
    { 
     "lat": 51.506321, 
     "lon": -0.127140 
    } 
    ] 
} 

Według ElasticSearch reference guide

filtr geo_distance może pracować z wieloma lokalizacjami/wskazuje każdego dokumentu. Gdy jedna lokalizacja/punkt pasuje do filtra, dokument zostanie uwzględniony w filtrze.

Czy możliwe jest utworzenie filtra odległości geograficznej, który sprawdza wszystkie lokalizacje w tablicy?

nie wydają się działać, niestety:

{ 
    "filter": { 
    "geo_distance": { 
     "distance": "100 km", 
     "locations": "40, -105" 
    } 
    } 
} 

rzuca "QueryParsingException[[myIndex] failed to find geo_point field [locations]" od locations nie jest pojedynczym geo_point ale tablicą geo_point s.

Odpowiedz

23

Czy w dokumencie zdefiniowano geo_point mapping?

curl -XDELETE 'http://localhost:9200/twitter/' 
curl -XPUT 'http://localhost:9200/twitter/' 

curl -XPUT 'http://localhost:9200/twitter/tweet/_mapping' -d ' 
{ 
    "tweet" : { 
     "properties" : { 
      "locations" : {"type" : "geo_point"} 
     } 
    } 
}' 

curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d ' 
{ 
    "user": "kimchy", 
    "postDate": "2009-11-15T13:12:00", 
    "message": "Trying out Elastic Search, so far so good?", 
    "locations" : [{ 
     "lat" : 50.00, 
     "lon" : 10.00 
    }, 
    { 
     "lat" : 40.00, 
     "lon" : 9.00 
    }] 
}' 

curl -XPUT 'http://localhost:9200/twitter/tweet/2' -d ' 
{ 
    "user": "kimchy", 
    "postDate": "2009-11-15T13:12:00", 
    "message": "Trying out Elastic Search, so far so good?", 
    "locations" : [{ 
     "lat" : 30.00, 
     "lon" : 8.00 
    }, 
    { 
     "lat" : 20.00, 
     "lon" : 7.00 
    }] 
}' 

curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d '{ 
    "query": { 
     "filtered" : { 
      "query" : { 
       "match_all" : {} 
      }, 
      "filter" : { 
       "geo_distance" : { 
        "distance" : "20km", 
        "tweet.locations" : { 
         "lat" : 40.00, 
         "lon" : 9.00 
        } 
       } 
      } 
     } 
    } 
}' 
+0

Tak, tam geo_point mapowanie dla lokalizacjach. – Max

+0

To powinno zadziałać, zobacz mój przykład. Którą wersję ES używasz? Przetestowałem to na 0.20.6. – Thorsten

+1

Właściwie to * działa * teraz po zniszczeniu oryginalnego indeksu. Określenie mapowania geo_point, a następnie wstawienie tablicy lokalizacji sprawiło, że moje wcześniejsze mapowanie było zbyt skomplikowane. Wielkie dzięki! – Max

3

Dla Elasticsearch wersji 5.1, na samym powyżej indeksu, zapytanie pójdzie tak,

curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d ' 
{ 
    "query": { 
     "bool": { 
      "must": { 
       "match_all": {} 
      }, 
      "filter": { 
       "geo_distance": { 
        "distance": "200km", 
        "locations": { 
         "lat": 40.00, 
         "lon": 9.00 
        } 
       } 
      } 
     } 
    } 
}' 
Powiązane problemy