지리공간 쿼리
MongoDB는 지리 공간적 데이터에 대한 쿼리 작업을 지원합니다. 이 섹션에서는 MongoDB의 지리 공간적 기능을 소개합니다.
호환성
다음 환경에서 호스팅되는 배포에 대한 지리 공간적 쿼리를 실행할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
MongoDB Atlas에서 호스팅되는 배포의 경우 쿼리 Filter 막대 또는 집계 빌더를 사용하여 UI에서 지리 공간적 쿼리를 실행할 수 있습니다. 자세히 알아보려면 Atlas에서 지리 공간적 쿼리 수행을 참조하세요.
지리 공간 데이터
MongoDB에서는 지리공간 데이터를 GeoJSON 객체 또는 legacy coordinate pairs로 저장할 수 있습니다.
GeoJSON 객체
지구와 같은 구의 기하학적 모양을 계산하려면 위치 데이터를 GeoJSON 객체로 저장합니다.
GeoJSON 데이터를 지정하려면 내장된 문서를 사용하세요.
GeoJSON 객체 유형을 지정하는
type
이라는 필드 및객체의 좌표를 지정하는
coordinates
라는 필드입니다.
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }
중요
위도 및 경도 좌표를 지정하는 경우 경도를 먼저 나열한 다음 위도를 나열합니다.
유효한 경도 값은
-180
~180
입니다(둘 모두 포함).유효한 위도 값은
-90
~90
입니다(둘 모두 포함).
예를 들어 GeoJSON 포인트를 지정하려면 다음을 수행합니다.
location: { type: "Point", coordinates: [-73.856077, 40.848447] }
MongoDB에서 지원되는 GeoJSON 객체 목록과 예시는 GeoJSON 객체를 참조하세요.
GeoJSON 객체에 대한 MongoDB 지리 공간적 쿼리는 구체에서 계산되며, MongoDB는 GeoJSON 객체에 대한 지리 공간적 쿼리에 WGS84 참고 시스템을 사용합니다.
레거시 좌표 쌍
유클리드 평면에서 거리를 계산하려면 위치 데이터를 legacy coordinate pairs로 저장하고 2d
인덱스를 사용하세요. 데이터를 GeoJSON 포인트 유형으로 수동 변환하는 경우에는 MongoDB가 2dsphere
인덱스를 사용하여 legacy coordinate pairs에 대한 구면 계산을 지원합니다.
데이터를 레거시 좌표 쌍으로 지정하려면 배열(선호되는 방법) 또는 내장된 문서를 사용할 수 있습니다.
- 배열을 통해 지정합니다(기본 설정):
<field>: [ <x>, <y> ] 위도 및 경도 좌표를 지정하는 경우 경도를 먼저 나열한 다음 위도를 나열합니다.
<field>: [<longitude>, <latitude> ] 유효한 경도 값은
-180
~180
입니다(둘 모두 포함).유효한 위도 값은
-90
~90
입니다(둘 모두 포함).
- 내장된 문서를 통해 지정합니다.
<field>: { <field1>: <x>, <field2>: <y> } 위도 및 경도 좌표를 지정하는 경우 필드 이름에 관계없이 첫 번째 필드에는 경도 값이 포함되고 두 번째 필드에는 위도 값이 포함되어야 합니다. 즉,
<field>: { <field1>: <longitude>, <field2>: <latitude> } 유효한 경도 값은
-180
~180
입니다(둘 모두 포함).유효한 위도 값은
-90
~90
입니다(둘 모두 포함).
일부 언어에서는 연관 맵 순서가 보장되지 않으므로 레거시 좌표 쌍을 지정하려면 내장된 문서보다 배열을 사용하는 것이 좋습니다.
지리 공간적 인덱스
MongoDB는 지리 공간적 쿼리를 지원하기 위해 다음과 같은 지리 공간적 인덱스 유형을 제공합니다.
2dsphere
2dsphere 인덱스는 지구와 유사한 구의 기하학을 계산하는 쿼리를 지원합니다.
2dsphere
인덱스를 만들려면 db.collection.createIndex()
메서드를 사용하고 문자열 리터럴 "2dsphere"
를 인덱스 형식으로 지정합니다.
db.collection.createIndex( { <location field> : "2dsphere" } )
여기서 <location field>
는 값이 GeoJSON 객체 또는 레거시 좌표 쌍인 필드입니다.
참고
geoJSON 점 배열이 포함된 필드에 인덱스를 만들려고 하면 인덱스 빌드가 실패하고 다음 오류가 반환됩니다.
MongoServerError: Index build failed
2dsphere
인덱스에 대한 자세한 내용은 2dsphere
인덱스를 참조하세요.
2d
2D 인덱스는 2차원 평면에서 도형을 계산하는 쿼리를 지원합니다. 인덱스는 구체에서 계산하는 $nearSphere
쿼리를 지원할 수 있지만, 가능하면 구체 쿼리에는 2dsphere
인덱스를 사용하는 것이 좋습니다.
2d
인덱스를 생성하려면, db.collection.createIndex()
메서드를 사용하여 위치 필드를 키로 지정하고 "2d"
문자열 리터럴을 다음과 같이 인덱스 유형으로 지정합니다.
db.collection.createIndex( { <location field> : "2d" } )
여기서 <location field>
는 값이 레거시 좌표 쌍인 필드입니다.
2d
인덱스에 대한 자세한 내용은 2d
인덱스를 참조하세요.
지리 공간적 인덱스 및 샤드 collection
collection을 샤딩할 때는 지리 공간적 인덱스를 샤드 키로 사용할 수 없습니다. 그러나 다른 필드를 샤드 키로 사용하여 샤드 collection에 지리 공간적 인덱스를 생성할 수 있습니다.
샤드 collection에서 지원되는 지리 공간적 작업은 다음과 같습니다.
$geoNear
집계 단계$near
및$nearSphere
쿼리 연산자
$geoWithin
및 $geoIntersects
를 사용하여 샤드 cluster의 지리 공간적 데이터를 쿼리할 수도 있습니다.
지원되는 쿼리
지리공간 쿼리
참고
구형 쿼리의 경우 2dsphere
인덱스 결과를 사용합니다.
구형 쿼리에 2d
인덱스를 사용하면 극점을 감싸는 구형 쿼리에 2d
인덱스를 사용하는 것처럼 잘못된 결과가 발생할 수 있습니다.
지리공간 쿼리 연산자
MongoDB는 다음과 같은 지리공간 쿼리 연산자를 제공합니다:
이름 | 설명 |
---|---|
예시를 포함한 자세한 내용은 참조 페이지를 참조하세요.
지리 공간적 집계 단계
MongoDB에서 제공하는 다음 지리적 공간 집계 파이프라인 단계:
단계 | 설명 |
---|---|
예시를 포함한 자세한 내용은 $geoNear
참고 페이지를 참조하세요.
지리공간 모델
MongoDB 지리공간 쿼리는 평평한 표면이나 구의 기하학적 구조를 해석할 수 있습니다.
2dsphere
인덱스는 구형 쿼리만 지원합니다(예: 구형 표면의 도형을 해석하는 쿼리).
2d
인덱스는 플랫 쿼리를 지원합니다(예 평평한 표면의 기하학을 해석하는 쿼리) 및 일부 구형 쿼리. 2d
색인은 일부 구형 쿼리를 지원하지만 이러한 구면 쿼리에 2d
색인을 사용하면 오류가 발생할 수 있습니다. 가능하면 구형 쿼리에는 2dsphere
인덱스를 사용합니다.
다음 표에는 각 지리 공간적 작업에 사용되는 지리 공간적 쿼리 연산자, 지원되는 쿼리가 나열되어 있습니다.
작업 | 구형/평면 쿼리 | 참고 사항 |
---|---|---|
구형 | ||
평면 | ||
구형 | GeoJSON 포인트와 2dsphere 인덱스를 사용하는 구형 쿼리의 경우 연산자보다는 이름에 구형 쿼리를 명시적으로 지정하는 | |
구형 | 대신 GeoJSON 점을 사용하세요. | |
$geoWithin : { $geometry : ... } | 구형 | |
$geoWithin : { $box : ... } | 평면 | |
$geoWithin : { $polygon : ... } | 평면 | |
$geoWithin : { $center : ... } | 평면 | |
$geoWithin : { $centerSphere : ... } | 구형 | |
구형 | ||
구형 | ||
평면 |
Atlas에서 지리 공간적 쿼리 수행
MongoDB Atlas UI를 사용하여 Atlas에서 지리 공간적 쿼리를 수행할 수 있습니다.
인덱스 만들기
지리 공간적 컬렉션에 지리 공간적 인덱스가 아직 없는 경우 인덱스를 만들어야 합니다.
컬렉션의 데이터베이스를 선택합니다.
왼쪽의 기본 패널과 왼쪽 측면의 Namespaces 에는 데이터베이스의 컬렉션이 나열됩니다.
컬렉션을 선택합니다.
왼쪽 또는 기본 패널에서 지리 공간 데이터가 포함된 컬렉션을 선택합니다. 기본 패널에는 Find, Indexes, Aggregation 보기가 표시됩니다.
인덱스 보기를 선택합니다.
Index 보기를 열면 Atlas는 컬렉션에 있는 모든 인덱스를 표시합니다.
지역 유형에 대한 인덱스 정의
Create Index 버튼을 누릅니다.
geo 유형 인덱스를 정의합니다. GeoJSON 객체를 인덱스하는 방법을 참조하세요.
지리 공간적 데이터 쿼리
찾기 뷰를 선택합니다.
지리 공간적 데이터를 포함하는 컬렉션에서 Find 탭을 선택하여 지리 공간적 컬렉션을 볼 수 있습니다.
쿼리를 입력합니다.
Filter 텍스트 상자에 쿼리를 입력합니다. 지리 공간적 쿼리 연산자를 사용하여 지리공간 데이터에 대한 관련 쿼리를 수행합니다. 지리 공간적 쿼리는 다음과 유사할 수 있습니다.
{ "coordinates": { $geoWithin: { $geometry: { type: "Polygon", coordinates: [ [ [-80.0, 10.00], [ -80.0, 9.00], [ -79.0, 9.0], [ -79.0, 10.00 ], [ -80.0, 10.0 ] ] ] } } } } 적용 버튼을 누릅니다.
Apply 버튼을 눌러 쿼리를 적용합니다. Atlas는 지리공간 데이터를 필터링하여 지리공간 쿼리와 일치하는 문서만 표시합니다.
MongoDB Atlas UI에서 지리공간 쿼리를 수행하기 위한 집계 파이프라인을 생성하고 실행할 수 있습니다.
지리 공간적 쿼리 집계 파이프라인 만들기
집계 단계를 선택합니다.
왼쪽 하단 패널의 Select 드롭다운에서 집계 단계를 선택합니다.
드롭다운 오른쪽에 있는 토글은 단계 활성화 여부를 나타냅니다.
$geoNear
단계를 사용하여 집계 파이프라인에서 지리 공간적 쿼리를 수행합니다.집계 단계를 입력합니다.
적절한 값으로 단계를 채웁니다. 댓글 모드가 활성화된 경우 파이프라인 빌더는 선택한 단계에 대한 구문 지침을 제공합니다.
단계를 수정하면 Atlas는 현재 단계의 결과를 기반으로 오른쪽에 있는 미리보기 문서를 업데이트합니다.
$geoNear
단계는 다음과 유사합니다.{ near: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, spherical: true, query: { category: "Parks" }, distanceField: "calcDistance" } 필요에 따라 다른 파이프라인 단계를 실행하세요.
필요에 따라 단계를 추가하여 집계 파이프라인을 완성합니다.
$out
또는$merge
를 추가하여 결과를 뷰나 현재 컬렉션에 쓸 수 있습니다.
예시
다음 문서를 사용하여 컬렉션 places
를 생성합니다.
db.places.insertMany( [ { name: "Central Park", location: { type: "Point", coordinates: [ -73.97, 40.77 ] }, category: "Parks" }, { name: "Sara D. Roosevelt Park", location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] }, category: "Parks" }, { name: "Polo Grounds", location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] }, category: "Stadiums" } ] )
다음 작업은 location
필드에 2dsphere
인덱스를 생성합니다:
db.places.createIndex( { location: "2dsphere" } )
위의 places
컬렉션에는 2dsphere
인덱스가 있습니다. 다음 쿼리는 지정된 GeoJSON 점에서 최소 1,000미터에서 최대 5,000미터 떨어진 문서를 $near
연산자를 사용하여 가장 가까운 것부터 가장 먼 것 순으로 정렬하여 반환합니다.
db.places.find( { location: { $near: { $geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, $minDistance: 1000, $maxDistance: 5000 } } } )
다음 작업은 $geoNear
집계 연산을 사용하여 쿼리 필터 { category:
"Parks" }
과 일치하는 문서를 지정된 GeoJSON 점에서 가장 가까운 순서에서 가장 먼 순서로 정렬하여 반환합니다:
db.places.aggregate( [ { $geoNear: { near: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, spherical: true, query: { category: "Parks" }, distanceField: "calcDistance" } } ] )