2016-06-20 4 views
0

ネストされたオブジェクトにジオロケーションのセットを格納するインデックスがあります。elasticsearchでネストされたオブジェクトを返す方法を制限する方法

{ 
    ......, 
    "geo_points" : [ 
    { 
     "lat" : ... 
     "lon" : ... 
    }, 
    ....... 
    ] 
} 

とクエリ

{ 
sort: { 
    _geo_distance: { 
     geo_points: { 
      lat: "", 
      lon: "" 
     }, 
     order: 'asc', 
     unit: 'km' 
    } 
}, 
query: { 
    filtered: { 
     query: { 
      bool: { 
       must: [ 
        { 
         range: { 
          endtime: {gte: ""} 
         } 
        }, 
        { 
         range:{ 
          starttime: {lte: ""} 
         } 
        } 
       ], 
       should: [ 
        { 
         nested: { 
          path: 'categories', 
          filter: { 
           bool: { 
            should: { terms: { 'categories.id' => [1,2,3,4]} } 
           } 
          } 
         } 
        } 
       ], 
       minimum_number_should_match: 1 
      } 
     }, 
     filter: { 
      geo_distance: { 
       distance: "25km", 
       geo_points: {lat: "",lon: ""} 
      } 
     } 
    } 

}, 
from: 0, size: 100 
} 

であり、それは地理クエリ(距離によってソート)するために使用され、私は唯一の場所(複数可)と一致してgeo_pointsを戻すことができるかどうかを知りたいですまたは

私は返信のみXの場所を言うことができますか?

これを行う既存の方法はありますかinner_hits?また、可能であればサンプルクエリを教えてもらえますか?

ありがとうございました。

答えて

0

私は適切な作り付けの方法を見つけることができませんでしたので、私は

import org.elasticsearch.common.geo.GeoDistance; 
import org.elasticsearch.common.unit.DistanceUnit; 
import org.elasticsearch.common.geo.GeoPoint; 

/*** 
* 
* usage 
* "script_fields": { 
*  "closest_points": { 
*   "script": { 
*    "lang": "groovy", 
*    "file": "sortedGeoPoints", 
*    "params": { 
*     "field": "lokasyonlar", 
*     "lon": 26.954897, 
*     "lat": 38.7762021, 
*     "method": "PLANE", 
*     "unit": "km", 
*     "order": "asc", 
*     "limit": 5 
*    } 
*   } 
*  } 
*  } 
* 
*/ 

if (doc[field].values.size() < limit){ 
    return doc[field] 
} 
else{ 
    def distanceUnit 
    def geoCalculator 
    switch (method){ 
     case "ARC" : 
      geoCalculator = GeoDistance.ARC 
      break 
     case "FACTOR" : 
      geoCalculator = GeoDistance.FACTOR 
      break 
     default: 
      geoCalculator = GeoDistance.PLANE 
      break 
    } 
    switch (unit) { 
     case "in" : //inch 
      distanceUnit = DistanceUnit.INCH 
      break 
     case "yd": //yards 
      distanceUnit = DistanceUnit.YARD 
      break 
     case "ft": //feet 
      distanceUnit = DistanceUnit.FEET 
      break 
     case "nmi": //NAUTICALMILES 
      distanceUnit = DistanceUnit.NAUTICALMILES 
      break 
     case "mm": // MILLIMETERS 
      distanceUnit = DistanceUnit.MILLIMETERS 
      break 
     case "cm": // CENTIMETERS 
      distanceUnit = DistanceUnit.CENTIMETERS 
      break 
     case "mi": // MILES 
      distanceUnit = DistanceUnit.MILES 
      break 
     case "m": // MILES 
      distanceUnit = DistanceUnit.METERS 
      break 
     default: 
      distanceUnit = DistanceUnit.KILOMETERS 
      break 
    } 
    def sortedGeoPoints = new TreeMap<Double, GeoPoint>() 
    for(i = 0; i < doc[field].values.size(); i++){ 
     def loc = doc[field].values[i] 
     sortedGeoPoints.put(geoCalculator.calculate(loc.lon, loc.lat, lon, lat, distanceUnit), loc) 
    } 
    def list 
    if(order == "desc"){ 
     list = new ArrayList<GeoPoint>(sortedGeoPoints.descendingMap().values()) //reversed 
    } 
    else{ 
     list = new ArrayList<GeoPoint>(sortedGeoPoints.values()) 
    } 
    return list.subList(0, limit) 
} 

とサンプルクエリ

curl -XPOST /geo/test/_search -d '{ 
    "fields": [ 
     "_source", 
     "distances" 
    ], 
    "query": { 
     "bool": { 
     "must": [ 
      { 
       "geo_distance": { 
        "distance": "100km", 
        "locations": { 
        "lon": 28.442826999999966, 
        "lat": 37.101167 
        } 
       } 
      } 
     ] 
     } 
    }, 
    "script_fields": { 
     "closest_points": { 
      "script": { 
       "lang": "groovy", 
       "file": "sortedGeoPoints", 
       "params": { 
        "field" : "locations", 
        "lon": 28.442826999999966, 
        "lat": 37.101167, 
        "method" : "PLANE", 
        "unit" : "km", 
        "order" : "asc", 
        "limit" : 3 
       } 
      } 
     } 
     }, 
    "sort": { 
     "_geo_distance": { 
     "locations": { 
      "lon": 28.442826999999966, 
      "lat": 37.101167 
     }, 
     "order": "asc", 
     "unit": "km" 
     } 
    } 
}' 

ユースケース&全文ができるやったので、ここでカスタムESスクリプトで私の問題を解決しましたgist

実際には、_geo_distanceソートから抽出できます。しかし、私はそこでそのような機能を持つのに十分とは考えていません。

私はこれをより良い組み込みオプションのために開いておきます。私たちに知らせてください。

関連する問題