๐ ์น ์ฌ์ฉ์ ํ๋ ๋ถ์ ๋์๋ณด๋ โ MongoDash (์ค๊ณยท์งํ ์ค)
๋ชฉ์ฐจ ๋ฐ๋ก๊ฐ๊ธฐ
1.๐ ํ๋ก์ ํธ ๊ฐ์
MongoDash๋ ์น ํ์ด์ง ๋ด์์ ์ฌ์ฉ์๊ฐ ๋ฐ์์ํค๋ ํด๋ฆญ, ํธ๋ฒ, ํธ๋ฒ ์ ์ง ์๊ฐ ๋ฑ์ ๋ง์ฐ์ค ์ด๋ฒคํธ๋ฅผ ์์งํ๊ณ , ์ด๋ฅผ ๋ถ์ยท์๊ฐํํ๋ ๋์๋ณด๋ ์๋น์ค์ ๋๋ค.
๋ง๋ค๊ฒ ๋ ๋ฐฐ๊ฒฝ
- ์ทจ์ ์ค๋น๋ก ํฌํธํด๋ฆฌ์ค๋ฅผ ๊ด๋ฆฌํ๊ณ ์์๋๋ฐ, ์ด๋ ๋ถ๋ถ์์ ๋ฉด์ ๊ด์ด ๊ด์ฌ์ ๊ฐ์ง๋์ง ๊ถ๊ธํด์ง
- ๊ทธ๋ฌ๋, ๋ ธ์ ํ์ด์ง์์ ๋ฐ๋ก ์คํฌ๋ฆฝํธ๋ฅผ ๋ฃ์ด ์ฌ์ฉ์ ์ด๋ฒคํธ๋ฅผ ์ถ์ ํ๊ธฐ ํ๋ฌ.
- ๊ทธ๋์ ์๋ก ํฌํธํด๋ฆฌ์ค ์ฌ์ดํธ๋ฅผ ์ ์ํ๊ณ , ์ด๋ ๋ถ๋ถ์ ๊ฐ์ฅ ๊ด์ฌ์์ด ํ๋์ง ์๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ํ๋ก์ ํธ๋ฅผ ์์ํจ
- ํ์ฌ ๋ณด๊ณ ์๋ ํ์ด์ง๊ฐ, ๋ฐ๋ก ์ ์ ์ด๋ฒคํธ๋ฅผ ์ง๊ณํ๊ธฐ ์ํด ๋ง๋ค์ด์ง ํฌํธํด๋ฆฌ์ค ์ฌ์ดํธ์
์ฃผ์ ๋ชฉ์
- ํน์ UI ์์ญ์์ ์ฌ์ฉ์๊ฐ ์ผ๋ง๋ ๋จธ๋ฌผ๋ ๋์ง ๋ถ์
- ํด๋ฆญ ๋ฐ์ ์์นยท๋น๋ยทํจํด ํ์
- ํธ๋ฒ ์๊ฐ ๊ธฐ๋ฐ ๊ด์ฌ๋ ๋ถ์
- ํฌํธํด๋ฆฌ์ค ๊ฐ์ ์ ์ํ ์ ๋์ ๊ทผ๊ฑฐ ์ ๊ณต
ํ์ฌ๋ ๊ธฐํ/์ค๊ณ ๋จ๊ณ์ด๋ฉฐ, MongoDB๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฒคํธ ๋ก๊ทธ๋ฅผ ์์ ์ ์ผ๋ก ์์งโฏโโฏ์ ์ฅโฏโโฏ์กฐํ ํ๋ ์๋ฒ ์ํคํ ์ฒ๋ฅผ ๊ตฌ์ฑ ์ค์ ๋๋ค.
2.โ๏ธ ์์คํ ๊ตฌ์กฐ (์ค๊ณ ๋จ๊ณ)
-
ํด๋ผ์ด์ธํธ โ Event Collector (ํ๋ก ํธ)
- ์์งํ ์ด๋ฒคํธ
mousemove(์ขํ๋ง, ์ผ์ ๊ฐ๊ฒฉ ์ํ๋ง)click(์ขํโฏ+โฏtimestamp)mouseenter / mouseleave(hover ์์/์ข ๋ฃ ์๊ฐ)hoverDuration(ํธ๋ฒ ์ ์ง ์๊ฐ ๊ณ์ฐ)
- ์ ์ก ๋ฐฉ์
- 5์ดโฏorโฏ300๊ฑด ๋จ์๋ก ๋ฐฐ์น ์ ์ก
- ์ด๋ฒคํธ๋ฅผ ์ฆ์ ์๋ฒ์ ๋ณด๋ด์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ ํ์ ์ ์ฅ โ ์ผ์ ๋ ์์ด๋ฉด
POSTํธ์ถ
- ์์งํ ์ด๋ฒคํธ
-
์๋ฒ โ Kotlinโฏ+โฏSpring Boot
- ๋น๋๊ธฐ API๋ฅผ ํตํด ๋๋ ์ด๋ฒคํธ ์์
- JSON ๋ฐฐ์ด ํํ๋ก ๋ค์ด์จ ์ด๋ฒคํธ๋ฅผ ํ์ฑ
- ๊ธฐ๋ณธ์ ์ผ๋ก MongoDB์ ์ ์ฅํ๋, ์ ์ฅ ๋ถํ๊ฐ ๋์ ๋๋ฅผ ๋๋นํด Redis ํ ์ฌ์ฉ ๊ณ ๋ ค
-
MongoDB โ Event Store
- ์ธ๋ถ ์ด๋ฒคํธ๋ฅผ Document ํํ๋ก ์ ์ฅ
- ํด๋ฆญ/ํธ๋ฒ๋ฅผ ๋ค๋ฅธ ์ปฌ๋ ์
์ผ๋ก ๋ถ๋ฆฌํ๊ฑฐ๋, ํ๋์ ์ปฌ๋ ์
์
typeํ๋๋ก ๊ตฌ๋ถํ ์ง ์ค๊ณ ๊ฒํ ์ค TTL์ธ๋ฑ์ค๋ก ์ค๋๋ ๋ก๊ทธ ์๋ ์ ๊ฑฐ ๊ธฐ๋ฅ ์์
-
Dashboard API
- ํน์ ์๊ฐ๋๋ณ ํด๋ฆญ ํํธ๋งต ์์ฑ
- UI ์์๋ณ ํ๊ท ํธ๋ฒ ์๊ฐ ๊ณ์ฐ
- ํ์ด์ง๋ณ ๊ด์ฌ๋ ๋ถ์ API ์ ๊ณต
3.๐ ํ์ฌ๊น์ง ์งํ๋ ๋ถ๋ถ
- WSLโฏ+โฏDocker๋ฅผ ํ์ฉํ MongoDB ๊ฐ๋ฐ ํ๊ฒฝ ๊ตฌ์ถ
mongod์คํ ๋ฐ ํฌํธ ํฌ์๋ฉ- Compass ๋ก DB/์ปฌ๋ ์ ์กฐํ ์ฑ๊ณต
mongosh๋ tar.gz ๋ฐ์ด๋๋ฆฌ ์ค์น๋ก ํด๊ฒฐ
- Kotlinโฏ+โฏSpring Boot ํ๋ก์ ํธ ์ด๊ธฐ ๊ตฌ์กฐ ์์ฑ
- Gradleโฏ+โฏKotlin DSL ๊ธฐ๋ฐ ์ค์
MongoConfig๋ฐRepository๋์ ํ์ธ/eventsAPI ์๋ํฌ์ธํธ ์์ ์ค
4.๐ ์ด๋ฒคํธ ๋ฐ์ดํฐ ๊ตฌ์กฐ (์ค๊ณ)
ํด๋ฆญ ์ด๋ฒคํธ
{
"type": "click",
"sessionId": "abc-123",
"timestamp": 1732501205000,
"x": 500,
"y": 620,
"target": "#login-button"
}ํธ๋ฒ ์์ / ์ข ๋ฃ ์ด๋ฒคํธ
{
"type": "hover_start",
"sessionId": "abc-123",
"timestamp": 1732501205000,
"x": 320,
"y": 450,
"target": "#menu-item-1"
}{
"type": "hover_end",
"sessionId": "abc-123",
"timestamp": 1732501208000,
"x": 320,
"y": 450,
"target": "#menu-item-1"
}ํธ๋ฒ ์ง์์๊ฐ ์ด๋ฒคํธ (์๋ฒ ๊ณ์ฐ)
{
"type": "hover_duration",
"sessionId": "abc-123",
"start": 1732501205000,
"end": 1732501208000,
"duration": 3000,
"target": "#menu-item-1"
}5.๐งฉ ์์๋๋ ์ด์
๐ฅ ๋ฌธ์ โฏ1 โ ํด๋ฆญยทํธ๋ฒ ์ด๋ฒคํธ ํญ์ฃผ ์ MongoDB ์ฑ๋ฅ ์ ํ
| ๋ฐฉ๋ฒ | ์ฅ์ | ๋จ์ |
|---|---|---|
insertMany | ๊ตฌํ ๊ฐ์ฅ ๋จ์ | ํญ์ฃผ ์ write ์ฑ๋ฅ ์ ํ |
BulkWrite | ๋๋ ์ด๋ฒคํธ ์ฒ๋ฆฌ ์ต์ ํ | ์ฝ๋ ๋ณต์ก |
| RedisโฏQueueโฏโโฏMongoโฏBatchWrite | ๋ถํ ์์ ๋ถ์ฐ | Redis ์ด์ ํ์ |
ํ์ฌ ํ๋จ: MVP ๋จ๊ณ์์๋ insertMany ๋ก ์์ํ๊ณ , ์ค์ ํธ๋ํฝ์์ ๋ณ๋ชฉ์ด ๋ณด์ด๋ฉด RedisโฏQueueโฏโโฏBulkWrite ๋ก ํ์ฅ ์์ .
๐ฅ ๋ฌธ์ โฏ2 โ ํธ๋ฒ ์ง์์๊ฐ ๊ณ์ฐ ์์น (ํ๋ก ํธโฏvsโฏ์๋ฒ)
| ์์น | ์ฅ์ | ๋จ์ |
|---|---|---|
| ํ๋ก ํธ | ๊ตฌํ ์ฌ์ | ์ฌ์ฉ์์ ์ปดํจํฐ ์ฑ๋ฅ/์ง์ฐ์ ์ํฅ |
| ์๋ฒ | ๋ฐ์ดํฐ ์ ํ๋ ๋์ | ์๋ฒ์ ์ถ๊ฐ ๋ก์ง ํ์ |
ํ์ฌ ํ๋จ: hoverโฏstart/end ์ด๋ฒคํธ๋ง ๋ฐ๊ณ , duration ์ ์๋ฒ์์ ๊ณ์ฐํ๋ ๋ฐฉํฅ์ด ์ ํฉ.
๐ฅ ๋ฌธ์ โฏ3 โ ๋์๋ณด๋ ์กฐํ ์๋ ๊ฐ์
| ๋ฐฉ๋ฒ | ์ฅ์ | ๋จ์ |
|---|---|---|
| Mongo ๋จ์ผ ์กฐํ | ๋จ์ | ๋๋ฆผ |
| Redis ์บ์ฑ | ๋น ๋ฆ | TTL ๊ด๋ฆฌ ํ์ |
| Materialized View | ์กฐํ ์ต์ ํ | ์ค๋ณต ์ ์ฅ ์ฆ๊ฐ |
ํ์ฌ ํ๋จ: ์ด๊ธฐ์๋ Mongo ๋จ์ผ ์กฐํ ๋ก ์์ํ๊ณ , ๋์๋ณด๋๊ฐ ์ค๋น๋๋ฉด Redis ์บ์ฑ ๋์ ์์ .
โป๏ธ ์์ฝ
- MongoDash๋ ์น ์ฌ์ฉ์ ๋ง์ฐ์ค ํ๋(ํด๋ฆญยทํธ๋ฒยทํธ๋ฒ ์๊ฐ)์ ์์งยท๋ถ์ยท์๊ฐํํ๋ ์๋น์ค์ ๋๋ค.
- ํ์ฌ ์ค๊ณ ๋จ๊ณ์ด๋ฉฐ DB ๊ตฌ์กฐยทAPI ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ถ ์ค์ ๋๋ค.
- ์ด๋ฒคํธ ์คํค๋ง์ ์์คํ ํ๋ฆ์ ๋ช ํํ ์ ์ํ์ผ๋ฉฐ, ์ฑ๋ฅยทํ์ฅ์ฑ์ ์ํ ์ฌ๋ฌ ์ต์ ์ ๊ฒํ ํ๊ณ ์์ต๋๋ค.
- ํฅํ BulkWrite, RedisโฏQueue, TTL ์ธ๋ฑ์ค ๋ฑ์ ๋์ ํด ์๋ฒ ํ์ฅ์ฑ์ ํ๋ณดํ ๊ณํ์ ๋๋ค.
์ ๋ด์ฉ์ ํ์ฌ ์งํ ์ํฉ๊ณผ ์ค๊ณ ์์ด๋์ด๋ฅผ ์ ๋ฆฌํ ๊ฒ์ด๋ฉฐ, ์ค์ ๊ตฌํ ์ ์ธ๋ถ ์ฌํญ์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.