Geospatial support i ElasticSearch

1.Introduktion

Elasticsearch er bedst kendt for sine søgefunktioner i fuldtekst, men det har også fuld geospatial support.

Vi kan finde mere om opsætning af Elasticsearch og komme i gang i denne tidligere artikel.

Lad os se på, hvordan vi kan gemme geodata i Elasticsearch, og hvordan vi kan søge disse data ved hjælp af geo-forespørgsler.

2. Geodatatype

For at aktivere geo-forespørgsler er vi nødt til at oprette kortlægningen af ​​indekset manuelt og eksplicit indstille feltkortlægningen.

Dynamisk kortlægning fungerer ikke under indstilling af kortlægning for geotyper.

Elasticsearch tilbyder to måder at repræsentere geodata på:

  1. Par i bredde- og længdegrad ved hjælp af geo-point felttype
  2. Kompleks form defineret i GeoJSON ved hjælp af feltform af geo-form

Lad os se nærmere på hver af ovenstående kategorier:

2.1. Geo Point-datatype

Geo-point felttype accepterer breddegrad-længdegradspar, der kan bruges til at:

  • Find punkter inden for en bestemt afstand fra det centrale punkt
  • Find punkter i en boks eller en polygon
  • Samlede dokumenter geografisk eller efter afstand fra det centrale punkt
  • Sorter dokumenter efter afstand

Nedenfor er prøvekortlægning for feltet for at gemme geo-punktdata:

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

Som vi kan se fra ovenstående eksempel, type til Beliggenhed felt er geo_point . Således kan vi nu tilvejebringe breddegrad-længdegradspar i Beliggenhed i placeringsfeltet.

2.2. Geo Shape Datatype

I modsætning til geo-point, geo form giver funktionaliteten til at gemme og søge i komplekse former som polygon og rektangel. Geo form datatype skal bruges, når vi vil søge i dokumenter, der indeholder andre former end geo-punkter.

Lad os se på kortlægning for datatype for geografisk form:

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

Nylige versioner af Elasticsearch nedbryder den leverede geoform i et trekantet mesh. Ifølge den officielle dokumentation giver dette næsten perfekt rumlig opløsning.

3. Forskellige måder at gemme Geo Point-data på

3.1. Længdegrad objekt

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

Her, geo-point Beliggenhed gemmes som et objekt med Breddegrad og længde som nøgler.

3.2. Par i længdegrad

{"location": "23.02,72.57"}

Her, Beliggenhed udtrykkes som et breddegrad-længdegradspar i et almindeligt strengformat. Bemærk, rækkefølgen af ​​bredde og længdegrad i strengformat.

3.3. Geo Hash

{"location": "tsj4bys"}

Vi kan også levere geo-punktdata i form af geo-hash som vist i eksemplet ovenfor. Vi kan bruge onlineværktøjet til at konvertere bredde-længdegrad til geo-hash.

3.4. Breddegrad i længdegrad

{"placering": [72.57, 23.02]}

Sekvensen for breddegrad-længdegrad vendes, når bredde- og længdegrad leveres som en matrix. Oprindeligt blev breddegrad-længdegradsparet brugt i både streng og i en matrix, men senere blev det vendt for at matche det format, der blev brugt af GeoJSON.

4. Forskellige måder at gemme Geo Shape-data på

4.1. Punkt

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

Her er den geoformtype, som vi prøver at indsætte, en punkt. Se venligst på Beliggenhed felt, har vi et indlejret objekt, der består af felter type og koordinater. Disse metafelter hjælper elastiksøgning med at identificere geoformen og dens faktiske data.

4.2. LineString

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

Her indsætter vi linestring geo form. Koordinaterne til linestring består af to punkter, dvs. start- og slutpunkt. LineString geo form er meget nyttigt til brug af navigationssager.

4.3. Polygon

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

Her indsætter vi polygon geo form. Se venligst på koordinater i ovenstående eksempel først og sidst koordinater i polygon skal altid matche, dvs. en lukket polygon.

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

  • MultiPoint
  • MultiLineString
  • MultiPolygon
  • Geometri Samling
  • Kuvert
  • Cirkel

Vi kan finde eksempler på ovenstående understøttede formater på det officielle ES-websted.

For alle strukturer, det indre type og koordinater er obligatoriske felter. Det er i øjeblikket ikke muligt at sortere og hente geografiske formfelter i Elasticsearch på grund af deres komplekse struktur. Således er den eneste måde at hente geografiske felter på fra kildefeltet.

5. Geo-forespørgsel om ElasticSearch

Nu, hvor vi ved, hvordan vi indsætter dokumenter, der indeholder geoformer, lad os dykke ned i at hente disse poster ved hjælp af geoformforespørgsler. Men før vi begynder at bruge Geo Queries, har vi brug for følgende maven-afhængigheder for at understøtte Java API til Geo Queries:

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

Vi kan også søge efter ovenstående afhængigheder i Maven Central repository.

Elasticsearch understøtter forskellige typer geo-forespørgsler, og de er som følger:

5.1. Geo Shape Query

Dette kræver geo_shape kortlægning.

Svarende til geo_shape type, geo_shape bruger GeoJSON-struktur til forespørgsel på dokumenter.

Nedenfor er et eksempel på en forespørgsel for at hente alle dokumenter, der falder inden for givet øverste venstre og nederste højre koordinater:

{"forespørgsel": {"bool": {"skal": {"match_all": {}}, "filter": {"geo_shape": {"region": {"form": {"type": "konvolut "," koordinater ": [[75.00, 25.0], [80.1, 30.2]]}," relation ":" inden for "}}}}}

Her, forhold bestemmer rumlige forholdsoperatører bruges på søgetid.

Nedenfor er listen over understøttede operatører:

  • INTERSEKTER - (standard) returnerer alle dokumenter, hvis geo_shape felt skærer forespørgselsgeometrien
  • FORSKYLD - henter alle dokumenter, hvis geo_shape felt har intet til fælles med forespørgselsgeometrien
  • INDEN FOR - får alle dokumenter, hvis geo_shape felt er inden for forespørgselsgeometrien
  • INDEHOLDER - returnerer alle dokumenter, hvis geo_shape felt indeholder forespørgselsgeometrien

På samme måde kan vi forespørge ved hjælp af forskellige GeoJSON-former.

Java-kode til ovenstående forespørgsel er som nedenfor:

Koordinere topLeft = ny Koordinat (74, 31.2); Koordinér 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-forespørgsel bruges til at hente alle dokumenter baseret på punktplacering. Nedenfor er et eksempel på en afgrænsningsfeltforespørgsel:

{"forespørgsel": {"bool": {"skal": {"match_all": {}}, "filter": {"geo_bounding_box": {"location": {"bottom_left": [28.3, 30.5], " top_right ": [31.8, 32.12]}}}}}

Java-kode til forespørgsel over ovenstående felt er som nedenfor:

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

Geo Bounding Box-forespørgsel understøtter lignende formater, som vi har i geo_point datatype. Eksempel på forespørgsler til understøttede formater kan findes på det officielle websted.

5.3. Geo Distance-forespørgsel

Geo-afstandsforespørgsel bruges til at filtrere alle dokumenter, der kommer med det angivne punkt for punktet.

Her er en prøve geo_afstand forespørgsel:

{"forespørgsel": {"bool": {"skal": {"match_all": {}}, "filter": {"geo_distance": {"distance": "10miles", "location": [31.131,29.976 ]}}}}}

Og her er Java-koden til ovenstående forespørgsel:

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

Svarende til geo_point, geo distance forespørgsel understøtter også flere formater til videregivelse af placeringskoordinater. Flere detaljer om understøttede formater kan findes på det officielle websted.

5.4. Geo Polygon Forespørgsel

En forespørgsel til filtrering af alle poster, der har punkter, der falder inden for den givne polygon af punkter.

Lad os se hurtigt på en prøveforespørgsel:

{"forespørgsel": {"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 til denne forespørgsel:

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 ("placering", allPoints);

Geo Polygon Query understøtter også formater nævnt nedenfor:

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

geo_point datatype er obligatorisk for at kunne bruge denne forespørgsel.

6. Konklusion

I denne artikel diskuterede vi forskellige kortlægningsmuligheder til indeksering af geodata, dvs. geo_point og geo_shape.

Vi gennemgik også forskellige måder at gemme på geodata og til sidst observerede vi geo-forespørgsler og Java API for at filtrere resultater ved hjælp af geo-forespørgsler.

Som altid er koden tilgængelig i dette GitHub-projekt.


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