Docs Menu

์ง€๋ฆฌ๊ณต๊ฐ„ ์ฟผ๋ฆฌ

MongoDB๋Š” ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ฟผ๋ฆฌ ์ž‘์—…์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” MongoDB์˜ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ธฐ๋Šฅ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํ™˜๊ฒฝ์—์„œ ํ˜ธ์ŠคํŒ…๋˜๋Š” ๋ฐฐํฌ์— ๋Œ€ํ•œ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • MongoDB Atlas: ํด๋ผ์šฐ๋“œ์—์„œ์˜ MongoDB ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ์™„์ „ ๊ด€๋ฆฌํ˜• ์„œ๋น„์Šค

  • MongoDB Enterprise: MongoDB์˜ ๊ตฌ๋… ๊ธฐ๋ฐ˜ ์ž์ฒด ๊ด€๋ฆฌ ๋ฒ„์ „

  • MongoDB Community: MongoDB์˜ ์†Œ์Šค ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋ฌด๋ฃŒ ์ž์ฒด ๊ด€๋ฆฌ ๋ฒ„์ „

MongoDB Atlas์—์„œ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๋ฐฐํฌ์„œ๋ฒ„์˜ ๊ฒฝ์šฐ ์ฟผ๋ฆฌ Filter ํ‘œ์‹œ์ค„ ๋˜๋Š” ์ง‘๊ณ„ ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ UI์—์„œ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํžˆ ์•Œ์•„๋ณด๋ ค๋ฉด Atlas์—์„œ ์ง€๋ฆฌ์  ๊ณต๊ฐ„ ์ฟผ๋ฆฌ ์ˆ˜ํ–‰์„ ์ฐธ์กฐํ•˜์„ธ์š”.

MongoDB์—์„œ๋Š” ์ง€๋ฆฌ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ GeoJSON ๊ฐ์ฒด ๋˜๋Š” legacy coordinate pairs๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ตฌ์™€ ๊ฐ™์€ ๊ตฌ์˜ ๊ธฐํ•˜ํ•™์  ๋ชจ์–‘์„ ๊ณ„์‚ฐํ•˜๋ ค๋ฉด ์œ„์น˜ ๋ฐ์ดํ„ฐ๋ฅผ 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 ์ธ๋ฑ์Šค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด db.collection.createIndex() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด "2dsphere"๋ฅผ ์ธ๋ฑ์Šค ํ˜•์‹์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

db.collection.createIndex( { <location field> : "2dsphere" } )

์—ฌ๊ธฐ์„œ <location field>๋Š” ๊ฐ’์ด GeoJSON ๊ฐ์ฒด ๋˜๋Š” ๋ ˆ๊ฑฐ์‹œ ์ขŒํ‘œ ์Œ์ธ ํ•„๋“œ์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ 

geoJSON ์  ๋ฐฐ์—ด์ด ํฌํ•จ๋œ ํ•„๋“œ์— ์ธ๋ฑ์Šค๋ฅผ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋ฉด ์ธ๋ฑ์Šค ๋นŒ๋“œ๊ฐ€ ์‹คํŒจํ•˜๊ณ  ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

MongoServerError: Index build failed

2dsphere ์ธ๋ฑ์Šค์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ 2dsphere ์ธ๋ฑ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

2D ์ธ๋ฑ์Šค๋Š” 2์ฐจ์› ํ‰๋ฉด์—์„œ ๋„ํ˜•์„ ๊ณ„์‚ฐํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋Š” ๊ตฌ์ฒด์—์„œ ๊ณ„์‚ฐํ•˜๋Š” $nearSphere ์ฟผ๋ฆฌ๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฐ€๋Šฅํ•˜๋ฉด ๊ตฌ์ฒด ์ฟผ๋ฆฌ์—๋Š” 2dsphere ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

2d ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด, db.collection.createIndex() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์น˜ ํ•„๋“œ๋ฅผ ํ‚ค๋กœ ์ง€์ •ํ•˜๊ณ  "2d" ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธ๋ฑ์Šค ์œ ํ˜•์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

db.collection.createIndex( { <location field> : "2d" } )

์—ฌ๊ธฐ์„œ <location field>๋Š” ๊ฐ’์ด ๋ ˆ๊ฑฐ์‹œ ์ขŒํ‘œ ์Œ์ธ ํ•„๋“œ์ž…๋‹ˆ๋‹ค.

2d ์ธ๋ฑ์Šค์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ 2d ์ธ๋ฑ์Šค๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ฐธ๊ณ 

๊ตฌํ˜• ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ฟผ๋ฆฌ์— 2d ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ ๋˜๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, 2d ์ธ๋ฑ์Šค๋Š” ๊ทน์ ์„ ๊ฐ์‹ธ๋Š” ๊ตฌํ˜• ์ฟผ๋ฆฌ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

MongoDB๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ฟผ๋ฆฌ ์—ฐ์‚ฐ์ž๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์‹œ๋ฅผ ํฌํ•จํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ฐ ์ฐธ์กฐ ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ด๋ฆ„
์„ค๋ช…

GeoJSON ๋„ํ˜•๊ณผ ๊ต์ฐจํ•˜๋Š” ๋„ํ˜•์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. 2dsphere ์ธ๋ฑ์Šค๋Š” $geoIntersects๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์  ๊ทผ์ฒ˜์— ์žˆ๋Š” ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ณต๊ฐ„ ์ธ๋ฑ์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. 2dsphere ๋ฐ 2d ์ธ๋ฑ์Šค๋Š” $near๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ์˜ ์ ์— ๊ทผ์ ‘ํ•œ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ณต๊ฐ„ ์ธ๋ฑ์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. 2dsphere ๋ฐ 2d ์ธ๋ฑ์Šค๋Š” $nearSphere๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ 

Time Series ์ปฌ๋ ‰์…˜์€ $geoNear ์ง‘๊ณ„ ๋‹จ๊ณ„๋ฅผ ํ†ตํ•ด 2dsphere ์ธ๋ฑ์Šค์— ๋Œ€ํ•œ ์ฟผ๋ฆฌ์—์„œ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ ฌํ•˜๋Š” ๊ฒƒ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Time Series ์ปฌ๋ ‰์…˜์—์„œ๋Š” $near ๋ฐ $nearSphere ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

MongoDB์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‹ค์Œ ์ง€๋ฆฌ์  ๊ณต๊ฐ„ ์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ ๋‹จ๊ณ„:

๋‹จ๊ณ„
์„ค๋ช…

์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ณต๊ฐ„ ์ ๊ณผ์˜ ๊ทผ์ ‘์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ๋œ ๋ฌธ์„œ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ์— $match, $sort, $limit์˜ ๊ธฐ๋Šฅ์„ ํ†ตํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ ๋ฌธ์„œ์—๋Š” ์ถ”๊ฐ€ ๊ฑฐ๋ฆฌ ํ•„๋“œ๊ฐ€ ํฌํ•จ๋˜๋ฉฐ ์œ„์น˜ ์‹๋ณ„์ž ํ•„๋“œ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$geoNear ์—๋Š” ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๊ณต๊ฐ„ ์ธ๋ฑ์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์‹œ๋ฅผ ํฌํ•จํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ $geoNear ์ฐธ๊ณ  ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

MongoDB ์ง€๋ฆฌ๊ณต๊ฐ„ ์ฟผ๋ฆฌ๋Š” ํ‰ํ‰ํ•œ ํ‘œ๋ฉด์ด๋‚˜ ๊ตฌ์˜ ๊ธฐํ•˜ํ•™์  ๊ตฌ์กฐ๋ฅผ ํ•ด์„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2dsphere ์ธ๋ฑ์Šค๋Š” ๊ตฌํ˜• ์ฟผ๋ฆฌ๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ๊ตฌํ˜• ํ‘œ๋ฉด์˜ ๋„ํ˜•์„ ํ•ด์„ํ•˜๋Š” ์ฟผ๋ฆฌ).

2d ์ธ๋ฑ์Šค๋Š” ํ”Œ๋žซ ์ฟผ๋ฆฌ(์˜ˆ: ํ‰ํ‰ํ•œ ํ‘œ๋ฉด์—์„œ ๊ธฐํ•˜ํ•™์„ ํ•ด์„ํ•˜๋Š” ์ฟผ๋ฆฌ) ๋ฐ ์ผ๋ถ€ ๊ตฌํ˜• ์ฟผ๋ฆฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. 2d ์ธ๋ฑ์Šค๋Š” ์ผ๋ถ€ ๊ตฌํ˜• ์ฟผ๋ฆฌ๋ฅผ ์ง€์›ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๊ตฌํ˜• ์ฟผ๋ฆฌ์— 2d ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋ฉด ๊ตฌํ˜• ์ฟผ๋ฆฌ์—๋Š” 2dsphere ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํ‘œ์—๋Š” ๊ฐ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ž‘์—…์— ์‚ฌ์šฉ๋˜๋Š” ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ฟผ๋ฆฌ ์—ฐ์‚ฐ์ž, ์ง€์›๋˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜์—ด๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ž‘์—…
๊ตฌํ˜•/ํ‰๋ฉด ์ฟผ๋ฆฌ
์ฐธ๊ณ  ์‚ฌํ•ญ

$near ( ์ด ์ค„๊ณผ ๋‹ค์Œ ์ค„์˜GeoJSON ์  2 , dsphere ์ธ๋ฑ์Šค)

๊ตฌํ˜•

GeoJSON ๋ฐ 2dsphere ์ธ๋ฑ์Šค ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ $nearSphere ์ œ๊ณตํ•˜๋Š” ์—ฐ์‚ฐ์ž ๋„ ์ฐธ์กฐํ•˜์„ธ์š”.

ํ‰๋ฉด

$nearSphere (GeoJSON ํฌ์ธํŠธ, 2dsphere ์ธ๋ฑ์Šค)

๊ตฌํ˜•

GeoJSON ํฌ์ธํŠธ ๊ณผ 2dsphere ์ธ๋ฑ์Šค ์‚ฌ์šฉํ•˜๋Š” ์ž‘์—…๊ณผ $near ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ตฌํ˜• ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ ์—ฐ์‚ฐ์ž๋ณด๋‹ค๋Š” ์ด๋ฆ„์— ๊ตฌํ˜• ์ฟผ๋ฆฌ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๋Š” $nearSphere $near๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌํ˜•

๋Œ€์‹  GeoJSON ์ ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

๊ตฌํ˜•

$geoWithin : { $box: ... }

ํ‰๋ฉด

$geoWithin : { $polygon: ... }

ํ‰๋ฉด

$geoWithin : { $center: ... }

ํ‰๋ฉด

๊ตฌํ˜•

๊ตฌํ˜•

$geoNear ์ง‘๊ณ„ ๋‹จ๊ณ„(2dsphere ์ธ๋ฑ์Šค)

๊ตฌํ˜•

$geoNear ์ง‘๊ณ„ ๋‹จ๊ณ„(2d ์ธ๋ฑ์Šค)

ํ‰๋ฉด

MongoDB Atlas UI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Atlas์—์„œ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1

์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ปฌ๋ ‰์…˜์— ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ธ๋ฑ์Šค๊ฐ€ ์•„์ง ์—†๋Š” ๊ฒฝ์šฐ ์ธ๋ฑ์Šค๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. ์ปฌ๋ ‰์…˜์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    ์™ผ์ชฝ์˜ ๊ธฐ๋ณธ ํŒจ๋„๊ณผ ์™ผ์ชฝ ์ธก๋ฉด์˜ Namespaces ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ปฌ๋ ‰์…˜์ด ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค.

  2. ์ปฌ๋ ‰์…˜์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    ์™ผ์ชฝ ๋˜๋Š” ๊ธฐ๋ณธ ํŒจ๋„์—์„œ ์ง€๋ฆฌ ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ์ปฌ๋ ‰์…˜์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํŒจ๋„์—๋Š” Find, Indexes, Aggregation ๋ณด๊ธฐ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

  3. ์ธ๋ฑ์Šค ๋ณด๊ธฐ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    Index ๋ณด๊ธฐ๋ฅผ ์—ด๋ฉด Atlas๋Š” ์ปฌ๋ ‰์…˜์— ์žˆ๋Š” ๋ชจ๋“  ์ธ๋ฑ์Šค๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

  4. ์ง€์—ญ ์œ ํ˜•์— ๋Œ€ํ•œ ์ธ๋ฑ์Šค ์ •์˜

    Create Index ๋ฒ„ํŠผ์„ ๋ˆ„๋ฆ…๋‹ˆ๋‹ค.

    ์ง€๋ฆฌ์  ์œ ํ˜• ์ธ๋ฑ์Šค ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. GeoJSON ๊ฐ์ฒด๋ฅผ์ธ๋ฑ์‹ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐธ์กฐํ•˜์„ธ์š”.

2
  1. ์ฐพ๊ธฐ ๋ทฐ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    ์ง€๋ฆฌ ๊ณต๊ฐ„์  ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๋Š” ์ปฌ๋ ‰์…˜์—์„œ Find ํƒญ์„ ์„ ํƒํ•˜์—ฌ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ปฌ๋ ‰์…˜์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ์ฟผ๋ฆฌ๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    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 ]
    ]
    ]
    }
    }
    }
    }
  3. ์ ์šฉ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฆ…๋‹ˆ๋‹ค.

    Apply ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์ฟผ๋ฆฌ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. Atlas๋Š” ์ง€๋ฆฌ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•˜์—ฌ ์ง€๋ฆฌ๊ณต๊ฐ„ ์ฟผ๋ฆฌ์™€ ์ผ์น˜ํ•˜๋Š” ๋ฌธ์„œ๋งŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

MongoDB Atlas UI์—์„œ ์ง€๋ฆฌ๊ณต๊ฐ„ ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์„ ์ƒ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
  1. ์ปฌ๋ ‰์…˜์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    ์™ผ์ชฝ์˜ ๊ธฐ๋ณธ ํŒจ๋„๊ณผ ์™ผ์ชฝ ์ธก๋ฉด์˜ Namespaces ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ปฌ๋ ‰์…˜์ด ๋‚˜์—ด๋ฉ๋‹ˆ๋‹ค.

  2. ์ปฌ๋ ‰์…˜์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    ์™ผ์ชฝ ๋˜๋Š” ๊ธฐ๋ณธ ํŒจ๋„์—์„œ ์ง€๋ฆฌ ๊ณต๊ฐ„ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ์ปฌ๋ ‰์…˜์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํŒจ๋„์—๋Š” Find, Indexes, Aggregation ๋ณด๊ธฐ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

  3. ์ง‘๊ณ„ ๋ณด๊ธฐ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    Aggregation ๋ณด๊ธฐ๋ฅผ ์ฒ˜์Œ ์—ด๋ฉด Atlas์— ๋นˆ ์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

2
  1. ์ง‘๊ณ„ ๋‹จ๊ณ„๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    ์™ผ์ชฝ ํ•˜๋‹จ ํŒจ๋„์˜ Select ๋“œ๋กญ๋‹ค์šด์—์„œ ์ง‘๊ณ„ ๋‹จ๊ณ„๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

    ๋“œ๋กญ๋‹ค์šด ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ํ† ๊ธ€์€ ๋‹จ๊ณ„ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

    $geoNear ๋‹จ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ง€๋ฆฌ ๊ณต๊ฐ„์  ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  2. ์ง‘๊ณ„ ๋‹จ๊ณ„๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    ์ ์ ˆํ•œ ๊ฐ’์œผ๋กœ ๋‹จ๊ณ„๋ฅผ ์ฑ„์›๋‹ˆ๋‹ค. ๋Œ“๊ธ€ ๋ชจ๋“œ๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ ํŒŒ์ดํ”„๋ผ์ธ ๋นŒ๋”๋Š” ์„ ํƒํ•œ ๋‹จ๊ณ„์— ๋Œ€ํ•œ ๊ตฌ๋ฌธ ์ง€์นจ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    ๋‹จ๊ณ„๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด Atlas๋Š” ํ˜„์žฌ ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

    $geoNear ๋‹จ๊ณ„๋Š” ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

    {
    near: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
    spherical: true,
    query: { category: "Parks" },
    distanceField: "calcDistance"
    }
  3. ํ•„์š”์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํŒŒ์ดํ”„๋ผ์ธ ๋‹จ๊ณ„๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

    ํ•„์š”์— ๋”ฐ๋ผ ๋‹จ๊ณ„๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ง‘๊ณ„ ํŒŒ์ดํ”„๋ผ์ธ์„ ์™„์„ฑํ•ฉ๋‹ˆ๋‹ค. $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"
}
}
] )