Geoshape 쿼리
Geoshape 쿼리
geoshape 쿼리를 사용해 geopoint 또는 geoshape 필드를 포함한 문서를 검색할 수 있어요. 쿼리 안에 정의된 geoshape를 사용하거나 사전 인덱싱된 geoshape를 사용해 문서를 필터링할 수 있습니다.
출처: 문서
본문
geoshape 쿼리를 사용해 geopoint 또는 geoshape 필드를 포함한 문서를 검색하세요. 쿼리 안에 정의된 geoshape를 사용하거나 사전 인덱싱된 geoshape를 사용해 문서를 필터링할 수 있어요.
검색 대상 문서 필드는 geo_point 또는 geo_shape로 매핑되어야 해요.
공간 관계 (Spatial relations)
geoshape 쿼리에 geoshape를 제공하면 문서의 geopoint와 geoshape 필드는 제공된 도형에 대해 다음 공간 관계를 사용해 매칭돼요.
| 관계 | 설명 | 지원 지리 필드 타입 |
|---|---|---|
INTERSECTS (기본값) |
geopoint 또는 geoshape가 쿼리에 제공된 도형과 교차하는 문서를 매칭함 | geo_point, geo_shape |
DISJOINT |
geoshape가 쿼리에 제공된 도형과 교차하지 않는 문서를 매칭함 | geo_shape |
WITHIN |
geoshape가 쿼리에 제공된 도형 안에 완전히 포함되는 문서를 매칭함 | geo_shape |
CONTAINS |
geoshape가 쿼리에 제공된 도형을 완전히 포함하는 문서를 매칭함 | geo_shape |
geoshape 쿼리에서 도형 정의하기
geoshape 쿼리에서 문서를 필터링할 도형을 쿼리 시점에 새 도형 정의를 제공하거나 다른 인덱스에 사전 인덱싱된 도형의 이름을 참조해 정의할 수 있어요.
새 도형 정의 사용하기 (Using a new shape definition)
geoshape 쿼리에 새 도형을 제공하려면 geo_shape 필드에 정의하세요. geoshape를 GeoJSON 형식으로 정의해야 해요.
다음 예시는 쿼리 시점에 정의된 geoshape와 일치하는 geoshape를 포함한 문서를 검색하는 방법을 보여줘요.
1단계: 인덱스 생성
먼저 인덱스를 만들고 location 필드를 geo_shape로 매핑하세요.
PUT /testindex
{
"mappings": {
"properties": {
"location": {
"type": "geo_shape"
}
}
}
}
2단계: 문서 인덱싱
point를 포함한 문서 하나와 polygon을 포함한 문서 하나를 인덱싱하세요.
PUT testindex/_doc/1
{
"location": {
"type": "point",
"coordinates": [ 73.0515, 41.5582 ]
}
}
PUT testindex/_doc/2
{
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
3단계: geoshape 쿼리 실행
마지막으로 문서를 필터링할 geoshape를 정의하세요. 다음 섹션들은 쿼리에서 다양한 geoshape를 제공하는 방법을 보여줘요. 다양한 geoshape 형식에 대한 자세한 내용은 Geoshape field type을 참조하세요.
Envelope
envelope는 [[minLon, maxLat], [maxLon, minLat]] 형식의 경계 사각형이에요. 제공된 envelope와 교차하는 geoshape 필드를 포함한 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "envelope",
"coordinates": [
[
71.0589,
42.3601
],
[
74.006,
40.7128
]
]
},
"relation": "WITHIN"
}
}
}
}
응답에는 두 문서가 모두 포함돼요.
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 0,
"hits": [
{
"_index": "testindex",
"_id": "1",
"_score": 0,
"_source": {
"location": {
"type": "point",
"coordinates": [
73.0515,
41.5582
]
}
}
},
{
"_index": "testindex",
"_id": "2",
"_score": 0,
"_source": {
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
}
]
}
}
Point
geoshape 필드가 제공된 point를 포함하는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "point",
"coordinates": [
72.8000,
41.6300
]
},
"relation": "CONTAINS"
}
}
}
}
Linestring
geoshape 필드가 제공된 linestring과 교차하지 않는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "linestring",
"coordinates": [[74.0060, 40.7128], [71.0589, 42.3601]]
},
"relation": "DISJOINT"
}
}
}
}
Linestring geoshape 쿼리는 WITHIN 관계를 지원하지 않아요.
Polygon
GeoJSON 형식에서는 polygon의 꼭짓점을 반시계 방향으로 나열하고 첫 꼭짓점과 마지막 꼭짓점이 같도록 polygon을 닫아야 해요.
geoshape 필드가 제공된 polygon 안에 있는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "polygon",
"coordinates": [
[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
]
]
},
"relation": "WITHIN"
}
}
}
}
Multipoint
geoshape 필드가 제공된 점들과 교차하지 않는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "multipoint",
"coordinates" : [
[74.0060, 40.7128],
[71.0589, 42.3601]
]
},
"relation": "DISJOINT"
}
}
}
}
Multilinestring
geoshape 필드가 제공된 선들과 교차하지 않는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "multilinestring",
"coordinates" : [
[[74.0060, 40.7128], [71.0589, 42.3601]],
[[73.7562, 42.6526], [72.6734, 41.7658]]
]
},
"relation": "disjoint"
}
}
}
}
Multilinestring geoshape 쿼리는 WITHIN 관계를 지원하지 않아요.
Multipolygon
geoshape 필드가 제공된 multipolygon 안에 있는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type" : "multipolygon",
"coordinates" : [
[
[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
],
[
[73.0515, 41.5582],
[72.6506, 41.5623],
[72.6734, 41.7658],
[73.0515, 41.5582]
]
],
[
[
[73.9146, 40.8252],
[73.8871, 41.0389],
[73.6853, 40.9747],
[73.9146, 40.8252]
]
]
]
},
"relation": "WITHIN"
}
}
}
}
Geometry collection
geoshape 필드가 제공된 polygon들 안에 있는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "geometrycollection",
"geometries": [
{
"type": "polygon",
"coordinates": [[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
]]
},
{
"type": "polygon",
"coordinates": [[
[73.0515, 41.5582],
[72.6506, 41.5623],
[72.6734, 41.7658],
[73.0515, 41.5582]
]]
}
]
},
"relation": "WITHIN"
}
}
}
}
linestring이나 multilinestring을 포함한 geometry collection을 가진 geoshape 쿼리는 WITHIN 관계를 지원하지 않아요.
사전 인덱싱된 도형 정의 사용하기 (Using a pre-indexed shape definition)
geoshape 쿼리를 구성할 때 다른 인덱스에 사전 인덱싱된 도형의 이름을 참조할 수도 있어요. 이 방법을 사용하면 인덱스 시점에 geoshape를 정의하고 검색 시점에 이름으로 참조할 수 있어요.
사전 인덱싱된 geoshape를 GeoJSON 또는 WKT(Well-Known Text) 형식으로 정의할 수 있어요. 다양한 geoshape 형식에 대한 자세한 내용은 Geoshape field type을 참조하세요.
indexed_shape 객체는 다음 파라미터를 지원해요.
| 파라미터 | 필수/선택 | 설명 |
|---|---|---|
id |
필수 | 사전 인덱싱된 도형을 포함한 문서의 문서 ID |
index |
선택 | 사전 인덱싱된 도형을 포함한 인덱스의 이름. 기본값은 shapes. |
path |
선택 | 사전 인덱싱된 도형을 포함한 필드의 필드 이름(경로). 기본값은 shape. |
routing |
선택 | 사전 인덱싱된 도형을 포함한 문서의 라우팅 값. 도형 문서가 사용자 지정 라우팅 값으로 인덱싱된 경우 필수. |
다음 예시는 다른 인덱스에 사전 인덱싱된 도형의 이름을 참조하는 방법을 보여줘요. 이 예시에서 pre-indexed-shapes 인덱스는 경계를 정의하는 도형을 포함하고, testindex 인덱스는 그 경계에 대해 확인되는 도형을 포함해요.
먼저 pre-indexed-shapes 인덱스를 만들고 이 인덱스의 boundaries 필드를 geo_shape로 매핑하세요.
PUT /pre-indexed-shapes
{
"mappings": {
"properties": {
"boundaries": {
"type": "geo_shape",
"orientation" : "left"
}
}
}
}
polygon의 다른 꼭짓점 방향 지정에 대한 자세한 내용은 Polygon을 참조하세요.
검색 경계를 지정하는 polygon을 pre-indexed-shapes 인덱스에 인덱싱하세요. polygon의 ID는 search_triangle이에요. 이 예시에서는 polygon을 WKT 형식으로 인덱싱할 거예요.
PUT /pre-indexed-shapes/_doc/search_triangle
{
"boundaries":
"POLYGON ((74.0060 40.7128, 71.0589 42.3601, 73.7562 42.6526, 74.0060 40.7128))"
}
아직 하지 않았다면 point를 포함한 문서 하나와 polygon을 포함한 문서 하나를 testindex 인덱스에 인덱싱하세요.
PUT /testindex/_doc/1
{
"location": {
"type": "point",
"coordinates": [ 73.0515, 41.5582 ]
}
}
PUT /testindex/_doc/2
{
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
geoshape가 search_triangle 안에 있는 문서를 검색하세요.
GET /testindex/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_shape": {
"location": {
"indexed_shape": {
"index": "pre-indexed-shapes",
"id": "search_triangle",
"path": "boundaries"
},
"relation": "WITHIN"
}
}
}
}
}
}
응답에는 두 문서가 모두 포함돼요.
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "testindex",
"_id": "1",
"_score": 1,
"_source": {
"location": {
"type": "point",
"coordinates": [
73.0515,
41.5582
]
}
}
},
{
"_index": "testindex",
"_id": "2",
"_score": 1,
"_source": {
"location": {
"type": "polygon",
"coordinates": [
[
[
73.0515,
41.5582
],
[
72.6506,
41.5623
],
[
72.6734,
41.7658
],
[
73.0515,
41.5582
]
]
]
}
}
}
]
}
}
geopoint 쿼리하기 (Querying geopoints)
geoshape 쿼리를 사용해 geopoint를 포함한 문서를 검색할 수도 있어요.
geopoint 필드에 대한 geoshape 쿼리는 기본 INTERSECTS 공간 관계만 지원하므로 relation 파라미터를 제공할 필요가 없어요.
geopoint 필드에 대한 geoshape 쿼리는 다음 geoshape를 지원하지 않아요.
- Points
- Linestrings
- Multipoints
- Multilinestrings
- 앞의 geoshape 타입 중 하나를 포함한 geometry collection
location이 geo_point인 매핑을 생성하세요.
PUT /testindex1
{
"mappings": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
두 점을 인덱스에 인덱싱하세요. 이 예시에서는 geopoint 좌표를 문자열로 제공할 거예요.
PUT /testindex1/_doc/1
{
"location": "41.5623, 72.6506"
}
PUT /testindex1/_doc/2
{
"location": "76.0254, 39.2467"
}
다양한 형식으로 geopoint 좌표를 제공하는 방법에 대한 정보는 Formats를 참조하세요.
제공된 polygon과 교차하는 geopoint를 검색하세요.
GET /testindex1/_search
{
"query": {
"geo_shape": {
"location": {
"shape": {
"type": "polygon",
"coordinates": [
[
[74.0060, 40.7128],
[73.7562, 42.6526],
[71.0589, 42.3601],
[74.0060, 40.7128]
]
]
}
}
}
}
}
응답은 문서 1을 반환해요.
{
"took": 21,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0,
"hits": [
{
"_index": "testindex1",
"_id": "1",
"_score": 0,
"_source": {
"location": "41.5623, 72.6506"
}
}
]
}
}
geopoint를 인덱싱할 때 그 좌표를 "latitude, longitude" 형식으로 지정했다는 점에 유의하세요. 일치 문서를 검색할 때 좌표 배열은 [longitude, latitude] 형식이에요. 따라서 문서 1은 결과에 반환되지만 문서 2는 반환되지 않아요.
파라미터 (Parameters)
geoshape 쿼리는 다음 파라미터를 받아들여요.
| 파라미터 | 데이터 타입 | 설명 |
|---|---|---|
ignore_unmapped |
Boolean | 매핑되지 않은 필드를 무시할지 여부를 지정함. true로 설정하면 쿼리는 매핑되지 않은 필드를 포함한 문서를 반환하지 않음. false로 설정하면 필드가 매핑되지 않았을 때 예외가 던져짐. 선택 사항. 기본값은 false. |
고비용 쿼리 (Expensive queries)
geoshape 필드는 기본적으로 BKD 트리에 도형을 저장하며, 해당 필드에 대한 쿼리는 search.allow_expensive_queries 설정과 무관하게 실행돼요.
tree 또는 strategy 파라미터로 매핑된 geoshape 필드는 대신 prefix 트리에 도형을 저장해요. prefix 트리 필드에 대한 쿼리는 search.allow_expensive_queries가 true일 때만 실행돼요.