2016-06-20 5 views
0

Ich habe einen Index, der Satz von Geo-Standorten in verschachtelten Objekt speichert.Wie Eingeschränkte zurückgegebene verschachtelte Objekte in Elasticsearch zu beschränken

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

und Abfrage ist

{ 
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 
} 

und es ist für geo-Abfragen (sortiert nach Entfernung) verwendet, würde ich gerne wissen, ob es möglich ist, mit der geo_points zurückzukehren Lage nur passende (n) oder

kann ich sagen, nur X-Standort (e) zurückgeben?

Gibt es einen bestehenden Weg, dies zu tun inner_hits? und können Sie mir auch eine Beispielabfrage geben, wenn es möglich ist?

Danke.

Antwort

0

löste ich mein Problem mit benutzerdefinierten ES-Skript, da ich nicht eine richtige Art und Weise eingebauten so hier, was ich tat

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) 
} 

und Beispielabfrage

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" 
     } 
    } 
}' 

Use Case & ganze Geschichte kann finden konnten, gefunden werden in gist

In der Tat kann es aus _geo_distance sort extrahiert werden. Ich glaube jedoch nicht genug, um solche Funktionalität dort zu haben.

Ich werde dies offen für bessere eingebaute Optionen, wenn es ist, lassen Sie es uns wissen

Verwandte Themen