Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ /

지리 공간적 쿼리로 식당 찾기

이 페이지의 내용

  • 개요
  • 왜곡
  • 레스토랑 검색

MongoDB의 지리 공간적 인덱싱을 사용하면 지리 공간적 형태와 점이 포함된 컬렉션에서 공간 쿼리를 효율적으로 실행할 수 있습니다. 이 튜로리얼에서는 지리 공간적 기능의 역량을 제시하고 다양한 접근 방식을 비교하기 위해 간단한 지리 공간 애플리케이션 쿼리를 작성하는 프로세스를 안내합니다.

이 튜토리얼은 지리 공간적 인덱스의 개념을 간략하게 소개한 다음 $geoWithin, $geoIntersects$nearSphere로 사용하는 방법을 선보입니다.

사용자가 뉴욕에서 레스토랑을 찾는 과정을 지원하는 모바일 애플리케이션을 디자인한다고 가정해 보겠습니다. 애플리케이션은 다음을 충족해야 합니다.

  • $geoIntersects를 사용하여 사용자의 현재 주변 환경을 파악합니다.

  • $geoWithin을 사용하여 주변의 레스토랑 수를 표시하고

  • $nearSphere사용하여 지정된 거리 내에 있는 레스토랑을 찾습니다.

이 튜토리얼은 2dsphere 인덱스를 사용하여 구형 기하학에서 이 데이터를 쿼리합니다.

구형 및 평면 도형에 대한 자세한 정보는 Geospatial Models에서 확인 가능합니다.

구형 기하학은 지구와 같은 3차원 구를 평면에 투영하는 속성 때문에 지도에 시각화될 때 왜곡을 유발합니다.

예를 들어, 경도 위도 점 (0,0), (80,0), (80,80)(0,80)으로 정의된 구형 정사각형 사양을 사용합니다. 다음 그림은 이 리전에 해당하는 영역을 묘사합니다.

구에 투영된 정사각형의 다이어그램.
클릭하여 확대

https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/neighborhoods.jsonhttps://raw.githubusercontent.com/mongodb/docs-assets/geospatial/restaurants.json 에서 예시 데이터베이스를 다운로드할 수 있습니다. 여기에는 restaurantsneighborhoods 컬렉션이 각각 포함되어 있습니다.

데이터세트를 다운로드한 후 데이터베이스로 가져옵니다.

mongoimport <path to restaurants.json> -c=restaurants
mongoimport <path to neighborhoods.json> -c=neighborhoods

지리 공간적 인덱스이며 거의 항상 $geoWithin$geoIntersects 쿼리의 성능 향상에 기여합니다.

이 데이터는 지리적 데이터이므로 mongosh를 사용하여 각 컬렉션에 2dsphere 인덱스를 생성합니다.

db.restaurants.createIndex({ location: "2dsphere" })
db.neighborhoods.createIndex({ geometry: "2dsphere" })

mongosh에서 새로 만든 restaurants 컬렉션의 항목을 검사합니다.

db.restaurants.findOne()

이 쿼리는 다음과 같은 문서를 반환합니다.

{
location: {
type: "Point",
coordinates: [-73.856077, 40.848447]
},
name: "Morris Park Bake Shop"
}

이 레스토랑 문서는 다음 그림에 표시된 위치에 해당합니다.

단일 지리 공간적 포인트의 지도.

이 튜토리얼은 2dsphere 인덱스를 사용하므로 location 필드의 기하학 데이터는 GeoJSON 형식을 준수해야 합니다.

이제 neighborhoods 컬렉션의 항목을 검사합니다.

db.neighborhoods.findOne()

이 쿼리는 다음과 같은 문서를 반환합니다.

{
geometry: {
type: "Polygon",
coordinates: [[
[ -73.99, 40.75 ],
...
[ -73.98, 40.76 ],
[ -73.99, 40.75 ]
]]
},
name: "Hell's Kitchen"
}

이 지오메트리는 다음 그림에 표시된 리전에 해당합니다.

지리 공간적 다각형의 지도.
클릭하여 확대

사용자의 모바일 디바이스가 사용자의 위치를 상당히 정확하게 파악할 수 있다고 가정하면 $geoIntersects를 통해 사용자의 현재 주변 지역을 간단히 찾을 수 있습니다.

사용자가 경도 -73.93414657, 위도 40.82302903에 있다고 가정합니다. 현재 주변 지역을 찾으려면 특수 $geometry 필드를 사용하여 GeoJSON 형식으로 포인트를 지정합니다.

db.neighborhoods.findOne({ geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] } } } })

이 쿼리는 다음과 같은 결과를 반환합니다.

{
"_id" : ObjectId("55cb9c666c522cafdb053a68"),
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[
-73.93383000695911,
40.81949109558767
],
...
]
]
},
"name" : "Central Harlem North-Polo Grounds"
}

특정 지역에 포함된 레스토랑을 모두 찾기 위한 쿼리도 수행할 수 있습니다. mongosh에서 다음을 실행하여 사용자가 위치한 지역을 찾은 다음 해당 지역 내의 레스토랑 수를 계산합니다.

var neighborhood = db.neighborhoods.findOne( { geometry: { $geoIntersects: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] } } } } )
db.restaurants.find( { location: { $geoWithin: { $geometry: neighborhood.geometry } } } ).count()

이 쿼리는 요청한 지역에 127개의 레스토랑이 있음을 알려주며 다음 그림에 시각화되어 있습니다.

지리 공간적 다각형에 존재하는 모든 레스토랑을 나타낸 지도.
클릭하여 확대

한 포인트에서 지정된 거리 내에 있는 레스토랑을 찾으려면 $geoWithin$centerSphere 사용하여 정렬되지 않은 순서로 결과를 반환하거나, 거리별로 정렬된 결과가 필요한 경우 $nearSphere$maxDistance를 사용할 수 있습니다.

원형 리전에서 레스토랑을 찾으려면 $geoWithin$centerSphere와 함께 사용합니다. $centerSphere는 중심과 반지름을 라디안 단위로 지정하여 원형 리전을 나타내는 MongoDB 전용 구문입니다.

$geoWithin 는 문서를 특정 순서대로 반환하지 않으므로 사용자에게 가장 먼 문서를 먼저 표시할 수 있습니다.

다음은 사용자로부터 약5km 이내에 있는 모든 레스토랑을 찾습니다.

db.restaurants.find({ location:
{ $geoWithin:
{ $centerSphere: [ [ -73.93414657, 40.82302903 ], 5 / 3963.2 ] } } })

$centerSphere의 두 번째 인수는 라디안 단위의 반지름을 허용하므로 이를 킬로미터 단위의 지구 반지름으로 나눠야 합니다. 거리 단위 간 변환에 대한 자세한 내용은 구형 연산자 거리를 라디안으로 변환하기에서 확인 가능합니다.

$nearSphere 를 사용하고 $maxDistance 텀을 미터 단위로 지정할 수도 있습니다. 이렇게 하면 사용자로부터 8km 이내에 있는 모든 식당이 가장 가까운 순서대로 정렬되어 반환됩니다.

var METERS_PER_MILE = 1609.34
db.restaurants.find({ location: { $nearSphere: { $geometry: { type: "Point", coordinates: [ -73.93414657, 40.82302903 ] }, $maxDistance: 5 * METERS_PER_MILE } } })

돌아가기

지리공간 쿼리

이 페이지의 내용