์ง๋ฆฌ๊ณต๊ฐ ์ฟผ๋ฆฌ
์ด ํ์ด์ง์ ๋ด์ฉ
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 ์ธ๋ฑ์ค๋ฅผ ์ฐธ์กฐํ์ธ์.
์ง๋ฆฌ๊ณต๊ฐ ์ฟผ๋ฆฌ
์ฐธ๊ณ
๊ตฌํ ๋ฐ์ดํฐ์ ๋ํ ์ฟผ๋ฆฌ์ 2d
์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ชป๋ ๊ฒฐ๊ณผ ๋๋ ์ค๋ฅ๊ฐ ๋ฐํ๋ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, 2d
์ธ๋ฑ์ค๋ ๊ทน์ ์ ๊ฐ์ธ๋ ๊ตฌํ ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ์ง ์์ต๋๋ค.
์ง๋ฆฌ๊ณต๊ฐ ์ฟผ๋ฆฌ ์ฐ์ฐ์
MongoDB๋ ๋ค์๊ณผ ๊ฐ์ ์ง๋ฆฌ ๊ณต๊ฐ์ ์ฟผ๋ฆฌ ์ฐ์ฐ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ์์๋ฅผ ํฌํจํ ์์ธํ ๋ด์ฉ์ ๊ฐ ์ฐธ์กฐ ํ์ด์ง๋ฅผ ์ฐธ์กฐํ์ธ์.
์ด๋ฆ | ์ค๋ช
|
---|---|
GeoJSON ๋ํ๊ณผ ๊ต์ฐจํ๋ ๋ํ์ ์ ํํฉ๋๋ค. | |
๊ฒฝ๊ณ GeoJSON ์ง์ค๋ฉํธ๋ฆฌ ๋ด์ ์ง์ค๋ฉํธ๋ฆฌ๋ฅผ ์ ํํฉ๋๋ค. | |
์ ๊ทผ์ฒ์ ์๋ ์ง๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ์ง๋ฆฌ ๊ณต๊ฐ์ ๊ณต๊ฐ ์ธ๋ฑ์ค๊ฐ ํ์ํฉ๋๋ค. | |
๊ตฌ์ ์ ์ ๊ทผ์ ํ ์ง๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. ์ง๋ฆฌ ๊ณต๊ฐ์ ๊ณต๊ฐ ์ธ๋ฑ์ค๊ฐ ํ์ํฉ๋๋ค. |
์ฐธ๊ณ
Time Series ์ปฌ๋ ์
์ $geoNear
์ง๊ณ ๋จ๊ณ๋ฅผ ํตํด 2dsphere ์ธ๋ฑ์ค์ ๋ํ ์ฟผ๋ฆฌ์์ ์ง๋ฆฌ ๊ณต๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํ๋ ๊ฒ์ ์ง์ํฉ๋๋ค. Time Series ์ปฌ๋ ์
์์๋ $near
๋ฐ $nearSphere
์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ง๋ฆฌ ๊ณต๊ฐ์ ์ง๊ณ ๋จ๊ณ
MongoDB์์ ์ ๊ณตํ๋ ๋ค์ ์ง๋ฆฌ์ ๊ณต๊ฐ ์ง๊ณ ํ์ดํ๋ผ์ธ ๋จ๊ณ:
๋จ๊ณ | ์ค๋ช
|
---|---|
์ง๋ฆฌ ๊ณต๊ฐ์ ๊ณต๊ฐ ์ ๊ณผ์ ๊ทผ์ ์ฑ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋ ๋ฌธ์ ์คํธ๋ฆผ์ ๋ฐํํฉ๋๋ค. ์ง๋ฆฌ ๊ณต๊ฐ์ ๊ณต๊ฐ ๋ฐ์ดํฐ์
|
์์๋ฅผ ํฌํจํ ์์ธํ ๋ด์ฉ์ $geoNear
์ฐธ๊ณ ํ์ด์ง๋ฅผ ์ฐธ์กฐํ์ธ์.
์ง๋ฆฌ๊ณต๊ฐ ๋ชจ๋ธ
MongoDB ์ง๋ฆฌ๊ณต๊ฐ ์ฟผ๋ฆฌ๋ ํํํ ํ๋ฉด์ด๋ ๊ตฌ์ ๊ธฐํํ์ ๊ตฌ์กฐ๋ฅผ ํด์ํ ์ ์์ต๋๋ค.
2dsphere
์ธ๋ฑ์ค๋ ๊ตฌํ ์ฟผ๋ฆฌ๋ง ์ง์ํฉ๋๋ค(์: ๊ตฌํ ํ๋ฉด์ ๋ํ์ ํด์ํ๋ ์ฟผ๋ฆฌ).
2d
์ธ๋ฑ์ค๋ ํ๋ซ ์ฟผ๋ฆฌ(์: ํํํ ํ๋ฉด์์ ๊ธฐํํ์ ํด์ํ๋ ์ฟผ๋ฆฌ) ๋ฐ ์ผ๋ถ ๊ตฌํ ์ฟผ๋ฆฌ๋ฅผ ์ง์ํฉ๋๋ค. 2d
์ธ๋ฑ์ค๋ ์ผ๋ถ ๊ตฌํ ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ์ง๋ง ์ด๋ฌํ ๊ตฌํ ์ฟผ๋ฆฌ์ 2d
์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ๊ฐ๋ฅํ๋ฉด ๊ตฌํ ์ฟผ๋ฆฌ์๋ 2dsphere
์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ค์ ํ์๋ ๊ฐ ์ง๋ฆฌ ๊ณต๊ฐ์ ์์ ์ ์ฌ์ฉ๋๋ ์ง๋ฆฌ ๊ณต๊ฐ์ ์ฟผ๋ฆฌ ์ฐ์ฐ์, ์ง์๋๋ ์ฟผ๋ฆฌ๊ฐ ๋์ด๋์ด ์์ต๋๋ค.
์์
| ๊ตฌํ/ํ๋ฉด ์ฟผ๋ฆฌ | ์ฐธ๊ณ ์ฌํญ |
---|---|---|
| ๊ตฌํ | GeoJSON |
| ํ๋ฉด | |
| ๊ตฌํ | GeoJSON ๊ตฌํ ์ฟผ๋ฆฌ์ ๊ฒฝ์ฐ ์ฐ์ฐ์๋ณด๋ค๋ ์ด๋ฆ์ ๊ตฌํ ์ฟผ๋ฆฌ๋ฅผ ๋ช
์์ ์ผ๋ก ์ง์ ํ๋ |
| ๊ตฌํ | ๋์ GeoJSON ์ ์ ์ฌ์ฉํ์ธ์. |
| ๊ตฌํ | |
| ํ๋ฉด | |
| ํ๋ฉด | |
| ํ๋ฉด | |
| ๊ตฌํ | |
๊ตฌํ | ||
๊ตฌํ | ||
ํ๋ฉด |
Atlas์์ ์ง๋ฆฌ ๊ณต๊ฐ์ ์ฟผ๋ฆฌ ์ํ
์์
๋ค์ ๋ฌธ์๋ฅผ ์ฌ์ฉํ์ฌ ์ปฌ๋ ์
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" } } ] )