Geopriestorová podpora v ElasticSearch

1.Úvod

Elasticsearch je známy predovšetkým vďaka svojim schopnostiam fulltextového vyhľadávania, ale ponúka aj úplnú geopriestorovú podporu.

Viac o nastavení Elasticsearch a o tom, ako začať, nájdete v tomto predchádzajúcom článku.

Poďme sa pozrieť na to, ako môžeme ukladať geografické údaje v Elasticsearch a ako môžeme tieto údaje prehľadávať pomocou geografických dotazov.

2. Geo dátový typ

Aby sme povolili geografické dotazy, musíme vytvoriť mapovanie indexu ručne a explicitne nastaviť mapovanie polí.

Dynamické mapovanie nebude fungovať pri nastavovaní mapovania pre geo typy.

Elasticsearch ponúka dva spôsoby, ako reprezentovať geodata:

  1. Páry zemepisná šírka a dĺžka pomocou typu poľa geografického bodu
  2. Komplexný tvar definovaný v GeoJSON pomocou typu poľa geografického tvaru

Pozrime sa podrobnejšie na každú z vyššie uvedených kategórií:

2.1. Dátový typ geografického bodu

Typ poľa geografického bodu akceptuje páry zemepisnej šírky a dĺžky, ktoré možno použiť na:

  • Nájdite body v určitej vzdialenosti od centrálneho bodu
  • Nájdite body v rámci poľa alebo mnohouholníka
  • Agregujte dokumenty geograficky alebo podľa vzdialenosti od centrálneho bodu
  • Zoraďte dokumenty podľa vzdialenosti

Nižšie je ukážka mapovania poľa na uloženie údajov geo bodu:

PUT / index_name {"mappings": {"TYPE_NAME": {"properties": {"location": {"type": "geo_point"}}}}}

Ako vidíme z vyššie uvedeného príkladu, typu pre umiestnenie pole je geo_point . Teraz teda môžeme v páre poskytnúť pár zemepisnej šírky a dĺžky umiestnenie v poli umiestnenia.

2.2. Dátový typ geografického tvaru

Na rozdiel od geo-bod, geo tvar poskytuje funkciu na ukladanie a vyhľadávanie zložitých tvarov, ako sú mnohouholníky a obdĺžniky. Geo tvar dátový typ sa musí použiť, ak chceme prehľadávať dokumenty, ktoré obsahujú iné tvary ako geografické body.

Poďme sa pozrieť na mapovanie pre dátový typ geografického tvaru:

PUT / index_name {"mappings": {"TYPE_NAME": {"properties": {"location": {"type": "geo_shape"}}}}}

Posledné verzie aplikácie Elasticsearch rozdeľujú poskytnutý geografický tvar na trojuholníkovú sieť. Podľa oficiálnej dokumentácie to poskytuje takmer dokonalé priestorové rozlíšenie.

3. Rôzne spôsoby ukladania údajov o geografických bodoch

3.1. Objekt zemepisnej šírky a dĺžky

PUT index_name / index_type / 1 {"location": {"lat": 23.02, "lon": 72.57}}

Tu, geografický bod umiestnenie sa uloží ako objekt s zemepisná šírka a zemepisná dĺžka ako kľúče.

3.2. Pár zemepisnej šírky a dĺžky

{"location": "23.02,72.57"}

Tu, umiestnenie je vyjadrená ako dvojica zemepisná šírka a dĺžka vo formáte obyčajného reťazca. Upozorňujeme, že postupnosť zemepisných šírok a dĺžok je vo formáte reťazca.

3.3. Geo hash

{"location": "tsj4bys"}

Môžeme tiež poskytnúť údaje o geografických bodoch vo forme geografického hashu, ako je uvedené v príklade vyššie. Pomocou online nástroja môžeme previesť zemepisnú šírku a dĺžku na geografický hash.

3.4. Pole zemepisnej dĺžky a šírky

{"location": [72.57, 23.02]}

Ak sú zemepisná šírka a dĺžka dodávané ako pole, poradie zemepisnej šírky a dĺžky je obrátené. Spočiatku sa pár zemepisnej šírky a dĺžky používal v reťazci aj v poli, neskôr sa to však obrátilo, aby sa zhodoval s formátom používaným v GeoJSON.

4. Rôzne spôsoby ukladania údajov geografického tvaru

4.1. Bod

POST / index / typ {"location": {"type": "point", "Coordinates": [72.57, 23.02]}}

Typ geografického tvaru, ktorý sa pokúšame vložiť, je a bod. Prosím, pozrite sa na umiestnenie pole, máme vnorený objekt pozostávajúci z polí typu a súradnice. Tieto meta polia pomáhajú programu Elasticsearch pri identifikácii geografického tvaru a jeho skutočných údajov.

4.2. LineString

POST / index / typ {"location": {"type": "linestring", "Coordinates": [[77.57, 23.02], [77.59, 23.05]]}}

Tu vkladáme linestring geo tvar. Súradnice pre linestring pozostáva z dvoch bodov, tj. počiatočného a koncového bodu. LineString geografický tvar je veľmi užitočný pre prípady použitia navigácie.

4.3. Polygón

POST / index / typ {"location": {"type": "polygon", "coordinates": [[[[10.0, 0.0], [11.0, 0.0], [11.0, 1.0], [10.0, 1.0], [ 10,0, 0,0]]]}}

Tu vkladáme mnohouholník geo tvar. Prosím, pozrite sa na súradnice vo vyššie uvedenom príklade najprv a posledný súradnice v polygóne by sa mali vždy zhodovať, t. j. uzavretý polygón.

Elasticsearch podporuje aj ďalšie štruktúry GeoJSON. Kompletný zoznam ďalších podporovaných formátov je uvedený nižšie:

  • MultiPoint
  • MultiLineString
  • MultiPolygon
  • GeometryCollection
  • Obálka
  • Kruh

Príklady vyššie podporovaných formátov nájdeme na oficiálnych stránkach ES.

Pre všetky štruktúry vnútorné typu a súradnice sú povinné polia. Triedenie a načítanie polí geografických tvarov nie je v súčasnosti v aplikácii Elasticsearch možné kvôli ich zložitej štruktúre. Jediný spôsob, ako načítať geografické polia, je teda zo zdrojového poľa.

5. ElasticSearch Geo Query

Teraz, keď vieme, ako vkladať dokumenty obsahujúce geografické tvary, sa ponorme do načítania týchto záznamov pomocou dotazov na geografické tvary. Ale skôr ako začneme používať Geo Queries, budeme potrebovať nasledujúce závislosti maven na podporu Java API pre Geo Queries:

 org.locationtech.spatial4j spatial4j 0,7 com.vividsolutions jts 1,13 xerces xercesImpl 

Vyššie uvedené závislosti môžeme vyhľadať aj v úložisku Maven Central.

Elasticsearch podporuje rôzne typy geografických dotazov a sú nasledujúce:

5.1. Dotaz na geografický tvar

To si vyžaduje geo_shape mapovanie.

Podobný geo_shape typ, geo_shape používa štruktúru GeoJSON na dopytovanie dokumentov.

Nižšie je uvedený ukážkový dopyt na načítanie všetkých spadajúcich dokumentov v rámci dané horné ľavé a pravé spodné súradnice:

{"query": {"bool": {"must": {"match_all": {}}, "filter": {"geo_shape": {"region": {"shape": {"type": "obálka "," súradnice ": [[75.00, 25.0], [80.1, 30.2]]}," vzťah ":" v rámci "}}}}}}

Tu, vzťah určuje operátory priestorových vzťahov použité v čase hľadania.

Nižšie je uvedený zoznam podporovaných operátorov:

  • PRECHODY - (predvolené) vráti všetky dokumenty, ktorých geo_shape pole pretína geometriu dotazu
  • DISJOINT - načíta všetky dokumenty, ktorých geo_shape pole nemá nič spoločné s geometriou dotazu
  • V RÁMCI - dostane všetky dokumenty, ktorých geo_shape pole je v rámci geometrie dotazu
  • OBSAHUJE - vráti všetky dokumenty, ktorých geo_shape pole obsahuje geometriu dotazu

Podobne môžeme dopytovať pomocou rôznych tvarov GeoJSON.

Kód Java pre vyššie uvedený dotaz je uvedený nižšie:

Súradnica topLeft = nová súradnica (74, 31,2); Coordinate bottomRight = new Coordinate (81.1, 24); GeoShapeQueryBuilder qb = QueryBuilders.geoShapeQuery ("región", nový EnvelopeBuilder (topLeft, bottomRight) .buildGeometry ()); qb.relation (ShapeRelation.INTERSECTS);

5.2. Dopyt na geografické ohraničenie

Dotaz Geo Bounding Box sa používa na načítanie všetkých dokumentov na základe umiestnenia bodu. Nižšie je uvedený príklad dotazu na ohraničujúci rámček:

{"query": {"bool": {"must": {"match_all": {}}, "filter": {"geo_bounding_box": {"location": {"bottom_left": [28.3, 30.5], " top_right ": [31.8, 32.12]}}}}}}

Kód Java pre dotaz nad ohraničovacím rámikom je uvedený nižšie:

QueryBuilders .geoBoundingBoxQuery ("umiestnenie"). SetCorners (31.8, 30.5, 28.3, 32.12);

Dotaz Geo Bounding Box podporuje podobné formáty ako my v geo_point Dátový typ. Ukážky dotazov na podporované formáty nájdete na oficiálnych stránkach.

5.3. Dotaz na geografickú vzdialenosť

Dotaz na geografickú vzdialenosť sa používa na filtrovanie všetkých dokumentov, ktoré majú zadaný rozsah bodu.

Tu je ukážka geo_distance dopyt:

{"query": {"bool": {"must": {"match_all": {}}, "filter": {"geo_distance": {"distance": "10miles", "location": [31.131,29.976 ]}}}}}

A tu je kód Java pre vyššie uvedený dotaz:

QueryBuilders .geoDistanceQuery ("umiestnenie"). Point (29,976, 31,131) .distance (10, DistanceUnit.MILES);

Podobný geo_point, dopyt na geografickú vzdialenosť tiež podporuje viac formátov na odovzdanie súradníc polohy. Viac podrobností o podporovaných formátoch nájdete na oficiálnych stránkach.

5.4. Geo Polygón Dopyt

Dotaz na filtrovanie všetkých záznamov, ktoré majú body, ktoré spadajú do daného polygónu bodov.

Poďme sa rýchlo pozrieť na ukážkový dopyt:

{"query": {"bool": {"must": {"match_all": {}}, "filter": {"geo_polygon": {"location": {"points": [{"lat": 22.733 , "lon": 68.859}, {"lat": 24.733, "lon": 68.859}, {"lat": 23, "lon": 70.859}]}}}}}}

A v kóde Java pre tento dopyt:

Zoznam allPoints = new ArrayList (); allPoints.add (nový GeoPoint (22.733, 68.859)); allPoints.add (nový GeoPoint (24 733, 68 859)); allPoints.add (nový GeoPoint (23, 70,859)); QueryBuilders.geoPolygonQuery ("umiestnenie", všetky body);

Geo Polygon Query podporuje aj formáty uvedené nižšie:

  • lat-long as an array: [lon, lat]
  • lat-long as a string: “lat, lon”
  • geo hash

geo_point údajový typ je povinný na použitie tohto dotazu.

6. Záver

V tomto článku sme diskutovali o rôznych možnostiach mapovania na indexovanie geografických údajov, t geo_point a geo_shape.

Tiež sme si prešli rôznymi spôsobmi ukladania geodata a nakoniec sme pozorovali geografické dotazy a rozhranie Java API na filtrovanie výsledkov pomocou geografických dotazov.

Tento kód je ako vždy k dispozícii v tomto projekte GitHub.


$config[zx-auto] not found$config[zx-overlay] not found