Geospatial Support i ElasticSearch

1.Introduksjon

Elasticsearch er best kjent for sine muligheter for fulltekstsøk, men det har også full geospatial støtte.

Vi kan finne mer om hvordan du setter opp Elasticsearch og kommer i gang i denne forrige artikkelen.

La oss ta en titt på hvordan vi kan lagre geodata i Elasticsearch og hvordan vi kan søke i disse dataene ved hjelp av geografiske spørsmål.

2. Geodatatype

For å aktivere geosøk, må vi opprette kartleggingen av indeksen manuelt og eksplisitt angi feltkartleggingen.

Dynamisk kartlegging fungerer ikke mens du angir kartlegging for geotyper.

Elasticsearch tilbyr to måter å representere geodata på:

  1. Par på breddegrad og lengdegrad ved hjelp av geo-punkt felttype
  2. Kompleks form definert i GeoJSON ved hjelp av geo-form felttype

La oss se nærmere på hver av kategoriene ovenfor:

2.1. Geo Point Data Type

Geo-point felttype aksepterer breddegrad / lengdegradspar som kan brukes til å:

  • Finn punkter innenfor en viss avstand fra sentralt punkt
  • Finn punkter i en boks eller en polygon
  • Samle dokumenter geografisk eller etter avstand fra det sentrale punktet
  • Sorter dokumenter etter avstand

Nedenfor er eksempelkartlegging for feltet for å lagre data om geo-punkt:

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

Som vi kan se fra eksemplet ovenfor, type til plassering feltet er geo_point . Dermed kan vi nå gi breddegrad / lengdegradspar i plassering i plasseringsfeltet.

2.2. Geo Shape Datatype

I motsetning til geo-point, geo form gir funksjonaliteten til å lagre og søke i komplekse former som polygon og rektangel. Geo form datatypen må brukes når vi vil søke i dokumenter som inneholder andre former enn geo-punkter.

La oss ta en titt på kartlegging for datatype for geografisk form:

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

Nylige versjoner av Elasticsearch bryter ned den oppgitte geoformen i et trekantet nett. I følge den offisielle dokumentasjonen gir dette nesten perfekt romlig oppløsning.

3. Ulike måter å lagre Geo Point-data på

3.1. Breddegrad lengdegrad objekt

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

Her, geo-point plassering blir lagret som et objekt med breddegrad og lengdegrad som nøkler.

3.2. Breddegrad par

{"location": "23.02,72.57"}

Her, plassering uttrykkes som et breddegrad / lengdegradspar i vanlig strengformat. Vær oppmerksom på sekvensen for bredde og lengdegrad i strengformat.

3.3. Geo Hash

{"location": "tsj4bys"}

Vi kan også gi geo-punktdata i form av geo-hash som vist i eksemplet ovenfor. Vi kan bruke det elektroniske verktøyet til å konvertere breddegrad og geo-hash.

3.4. Lengdegrad breddegrad

{"location": [72.57, 23.02]}

Sekvensen for breddegrad og lengdegrad reverseres når breddegrad og lengdegrad leveres som en matrise. Opprinnelig ble breddegrad-lengdegradsparet brukt i både streng og i en matrise, men senere ble det reversert for å matche formatet som ble brukt av GeoJSON.

4. Ulike måter å lagre Geo Shape Data på

4.1. Punkt

POST / indeks / type {"location": {"type": "point", "coordinates": [72.57, 23.02]}}

Her er geoformtypen vi prøver å sette inn en punkt. Ta en titt på plassering felt, har vi et nestet objekt som består av felt type og koordinater. Disse metafeltene hjelper Elasticsearch med å identifisere geografisk form og dens faktiske data.

4.2. LineString

POST / indeks / type {"location": {"type": "linestring", "coordinates": [[77.57, 23.02], [77.59, 23.05]]}}

Her setter vi inn linjering geo form. Koordinatene for linjering består av to punkter, dvs. start- og sluttpunkt. LineString geo form er veldig nyttig for brukstilfeller for navigering.

4.3. Polygon

POST / indeks / type {"location": {"type": "polygon", "koordinater": [[[10.0, 0.0], [11.0, 0.0], [11.0, 1.0], [10.0, 1.0], [ 10.0, 0.0]]]}}

Her setter vi inn polygon geo form. Ta en titt på koordinater i eksemplet ovenfor, først og siste koordinater i polygon skal alltid stemme overens, dvs. en lukket polygon.

Elasticsearch støtter også andre GeoJSON-strukturer. En komplett liste over andre støttede formater er som nedenfor:

  • MultiPoint
  • MultiLineString
  • MultiPolygon
  • GeometryCollection
  • Konvolutt
  • Sirkel

Vi kan finne eksempler på formater som støttes ovenfor på det offisielle ES-nettstedet.

For alle strukturer, det indre type og koordinater er obligatoriske felt. Det er for øyeblikket ikke mulig å sortere og hente geografiske formfelt i Elasticsearch på grunn av deres komplekse struktur. Dermed er den eneste måten å hente ut geofelt fra kildefeltet.

5. ElasticSearch Geo Query

Nå som vi vet hvordan vi setter inn dokumenter som inneholder geoformer, la oss dykke inn i å hente disse postene ved hjelp av geoformspørsmål. Men før vi begynner å bruke Geo Queries, trenger vi følgende avhengighetsavhengigheter for å støtte Java API for Geo Queries:

 org.locationtech.spatial4j spatial4j 0.7 com.vividsolutions jts 1.13 xerces xercesImpl 

Vi kan også søke etter de ovennevnte avhengighetene i Maven Central repository.

Elasticsearch støtter forskjellige typer geografiske spørsmål, og de er som følger:

5.1. Geo Shape Query

Dette krever geo_shape kartlegging.

Lik geo_shape type, geo_shape bruker GeoJSON-struktur for å spørre dokumenter.

Nedenfor er et eksempelspørsmål for å hente alle dokumentene som faller innenfor gitt koordinater øverst til venstre og nederst til høyre:

{"query": {"bool": {"must": {"match_all": {}}, "filter": {"geo_shape": {"region": {"shape": {"type": "envelope "," koordinater ": [[75.00, 25.0], [80.1, 30.2]]}," relation ":" innenfor "}}}}}

Her, forhold bestemmer romlige forholdsoperatører brukt på søketid.

Nedenfor er listen over støttede operatører:

  • INTERSEKTER - (standard) returnerer alle dokumenter hvis geo_shape felt krysser spørringsgeometrien
  • SKADE - henter alle dokumenter hvis geo_shape feltet har ingenting til felles med spørringsgeometrien
  • INNENFOR - får alle dokumenter hvis geo_shape feltet er innenfor spørringsgeometrien
  • INNEHOLDER - returnerer alle dokumenter hvis geo_shape feltet inneholder spørringsgeometrien

På samme måte kan vi spørre med forskjellige GeoJSON-former.

Java-kode for ovennevnte spørring er som nedenfor:

Koordinatopp Venstre = ny Koordinat (74, 31.2); Koordinere bottomRight = ny Koordinat (81.1, 24); GeoShapeQueryBuilder qb = QueryBuilders.geoShapeQuery ("region", ny EnvelopeBuilder (topLeft, bottomRight) .buildGeometry ()); qb.relation (ShapeRelation.INTERSECTS);

5.2. Geo Bounding Box Query

Geo Bounding Box-spørring brukes til å hente alle dokumentene basert på punktplassering. Nedenfor er et eksempel på en avgrensningsrute:

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

Java-kode for ovennevnte spørsmål er som nedenfor:

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

Geo Bounding Box-spørring støtter lignende formater som vi har i geo_point data-type. Eksempel på spørsmål for støttede formater kan bli funnet på det offisielle nettstedet.

5.3. Geo Distance Query

Geoavstandsspørring brukes til å filtrere alle dokumenter som kommer med det angitte punktområdet.

Her er et utvalg geoavstand spørsmål:

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

Og her er Java-koden for ovennevnte spørsmål:

QueryBuilders .geoDistanceQuery ("location") .point (29.976, 31.131) .distance (10, DistanceUnit.MILES);

Lik geo_point, geo avstand spørring støtter også flere formater for å sende plasseringskoordinater. Mer informasjon om støttede formater finner du på det offisielle nettstedet.

5.4. Geo Polygon Spørsmål

Et spørsmål om å filtrere alle poster som har poeng som faller innenfor den gitte polygonen av poeng.

La oss se raskt på et eksempelspørsmål:

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

Og ved Java-koden for dette spørsmålet:

Liste allPoints = ny ArrayList (); allPoints.add (ny GeoPoint (22.733, 68.859)); allPoints.add (ny GeoPoint (24.733, 68.859)); allPoints.add (ny GeoPoint (23, 70.859)); QueryBuilders.geoPolygonQuery ("location", allPoints);

Geo Polygon Query støtter også formater nevnt nedenfor:

  • lat-long som en matrise: [lon, lat]
  • lat-lang som en streng: “lat, lon”
  • geo hash

geo_point datatype er obligatorisk for å kunne bruke dette spørsmålet.

6. Konklusjon

I denne artikkelen diskuterte vi forskjellige kartleggingsalternativer for indeksering av geodata, dvs. geo_point og geo_shape.

Vi gikk også gjennom forskjellige måter å lagre på geodata og til slutt observerte vi geo-spørringer og Java API for å filtrere resultater ved hjelp av geo-spørringer.

Som alltid er koden tilgjengelig i dette GitHub-prosjektet.


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