이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌8 - MongoDB - 2년 전 등록

공간 쿼리 연산자, 투사 연산자

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

안녕하세요. 이번 시간에는 공간, 투사 쿼리 연산자에 대해서 알아보겠습니다.

공간 쿼리 연산자

몽고DB의 장점은 위치 정보를 계산하기 쉽습니다. 예를 들면 두 지점간의 거리를 구하거나, 한 지점으로부터 100m 떨어진 모든 가게를 가져온다든가 하는 계산이 용이합니다.

주의할 점은 공간 쿼리 연산자를 사용하기 위해서는 위치 정보 필드의 index2d2dsphere로 지정해야 합니다. 2d는 일반 좌표를 사용할 때 지정합니다. [경도(longitude), 위도(latitude)] 순으로 배열을 만들고, 경도는  ±180, 위도는  ±90의 범위를 가집니다.

2dsphereGeoJSON 좌표를 사용할 때 지정합니다. GeoJSON 객체는 { type: 타입, coordinates: [ 경도, 위도 ] } 형식으로 표현됩니다. 타입에는  Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection 등이 있습니다.Point를 제외하고는 coordinates: [[경도1, 위도1], [경도2, 위도2], ...] 이렇게 여러 점을 한 번에 표현할 수 있습니다. 여러 도형을 표현할 수 있는 게 장점입니다.

$near, $nearSphere

기준점으로부터 가까운 점들을 정렬하여 찾아줍니다. $nearSphere은 GeoJSON 객체에 대해서도 찾아줍니다. GeoJSON 객체를 사용하려면 $geometry 쿼리 안에 넣어주면 됩니다.

{ $near: [경도, 위도] }
{ $nearSphere: {
  $geometry: {
    type: 'Point',
    coordinates: [경도, 위도]
  }
} }

$maxDistance, $minDistance

$near이나 $nearSphere과 조합하여 기준점으로부터 일정 거리 이상(minDistance) 일정 거리 이하(maxDistance)에 해당되는 점들을 조회합니다. minDistance는 2dsphere일 경우에만 사용가능합니다. GeoJSON 객체가 아니면 미터 대신에 라디안이라는 거리 단위를 사용합니다. 라디안을 킬로미터로 바꾸려면 6378.1을 곱해야 하고, 킬로미터를 라디안으로 바꾸려면 6378.1을 나눠야 합니다. 미터로 바꾸려면 6378100을 나눠야겠죠?

{ $near: [경도, 위도], $maxDistance: 라디안 }
{ $nearSphere: {
  $geometry: {
    type: 'Point',
    coordinates: [경도, 위도]
  },
  $maxDistance: 미터,
  $minDistance: 미터,
} } 

$geoWithin

아래의 $center, $centerSphere $box, $polygon 등과 혼합하여 사용합니다. 해당 도형 안의 점들을 찾아줍니다. GeoJSON 객체는 $centerSphere을 제외하고는 혼합하지 않고 사용해도 됩니다.

$geoWithin: {
  $geometry: {
    type: "Polygon" 또는 "MultiPolygon",
    coordinates: [ 좌표들 ]
  }
}

$center, $centerSphere

중심이 경도, 위도이고 반지름이 반경인 원 안의 점들을 찾아줍니다. 100m 안의 상점, 500m 안의 상점 등등을 찾을 때 자주 쓰입니다. $center는 GeoJSON 객체를 찾지 않기 때문에 (2d index만 가능) GeoJSON 객체를 사용하려면 $centerSphere 쿼리를 사용해야 합니다.

{ $geoWithin: { $center: [[경도, 위도], 라디안] } }

$box

정사각형 안의 점들을 찾아줍니다. $box 배열의 첫 번째 요소가 정사각형 좌하점의 경도 위도이고, 두 번째 요소가 우상점의 경도 위도입니다. 2d index만 가능하므로 GeoJSON은 찾지 않습니다. GeoJSON을 찾으려면 그냥 $geometry 쿼리에서 찾으면 됩니다.

{ $geoWithin: { $box: [[경도, 위도], [경도, 위도]] } }

$polygon

다각형 안의 점을 찾아줍니다. 2d index만 가능하므로 GeoJSON은 찾지 않습니다. 다각형이니까 각 꼭지점 좌표를 모두 넣어주면 됩니다.

{ $geoWithin: { $polygon: [[경도1, 위도1], [경도2, 위도2], ...] } }

$geoIntersects

$geoWithin과 유사하지만, 내부에 있지 않아도 겹치는 것까지 찾아줍니다.

투사 연산자

투사(projection) 쿼리 연산자는 조회 후 내용의 일부만 가져오도록 하는 연산자입니다. 배열의 일부만 가져올 때 사용합니다. projection이기 때문에 두 번째 인자로만(투사 부분) 사용합니다.

db.monsters.find({ 쿼리 }, { 투사 });

$

배열의 몇 번째 요소를 가져올 지 결정합니다. { 'comments.$': 1 } 의 경우 comments 필드의 두 번째 요소만 가져옵니다. (0부터 시작)

{ 배열필드명.$: 숫자 }

$elemMatch

전 시간에도 $elemMatch가 있었는데요. 이번 시간의 $elemMatch는 좀 다릅니다. 일단 쿼리가 아니라 투사 옵션에 사용되는 겁니다. 배열 안에 객체들이 있을 때 일치하는 첫 번째 객체만 가져옵니다.

{ 배열필드: { $elemMatch: { 객체속성: 속성값 } }

$slice

숫자만큼의 배열 요소만 앞에서부터 잘라서 가져옵니다. 만약 숫자가 음수면 뒤에서부터 자릅니다. 첫 몇 개 또는 뒤에서 몇 개를 가져올 때 편합니다.

{ 배열필드: { $slice: 숫자 } }

다음 시간은 필드 수정 연산자에 대해 알아보겠습니다!

목록
투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

아직 댓글이 없습니다.