๋ฌธ์„œ ๋ฉ”๋‰ด

๋ฌธ์„œ ํ™ˆ โ†’ Atlas App Services

๊ด€๊ณ„

์ด ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ

  • ๊ฐœ์š”
  • ์นด๋””๋„๋ฆฌํ‹ฐ
  • To-One
  • To-Many
  • ๋‚ด์žฅ๋œ ๊ฐ์ฒด ๊ด€๊ณ„
  • ๋‹ค๋ฅธ ์ปฌ๋ ‰์…˜์— ๋‚ด์žฅ๋œ ๊ฐ์ฒด
  • ๋ชฉ๋ก์— ๋‚ด์žฅ๋œ ๊ฐ์ฒด
  • ๊ด€๊ณ„ ์ •์˜
  • 1. ์Šคํ‚ค๋งˆ ์ •์˜
  • 2. ์ƒˆ ๊ด€๊ณ„ ๋งŒ๋“ค๊ธฐ
  • 3. ๊ด€๊ณ„ ๊ตฌ์„ฑ
  • 4. ๊ด€๊ณ„ ๋ฐฐํฌ

๊ด€๊ณ„๋Š” ๋‘ ๋ฌธ์„œ ์‚ฌ์ด์˜ ์—ฐ๊ฒฐ์ž…๋‹ˆ๋‹ค. ๊ด€๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์„œ๊ฐ€ ๋ณ„๋„์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋‚˜ ์ปฌ๋ ‰์…˜์— ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ์ฝ๊ธฐ ๋ฐ ์“ฐ๊ธฐ ์ž‘์—…์—์„œ ๊ด€๋ จ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์ฟผ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

'์†Œ์Šค' MongoDB ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•˜๊ณ  '์™ธ๋ถ€' ์ปฌ๋ ‰์…˜์˜ ๋ฌธ์„œ์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. Atlas App Services๋Š” ์†Œ์Šค ํ•„๋“œ์˜ ๊ฐ’์„ ์ฐธ์กฐํ•˜๋Š” ์™ธ๋ถ€ ๋ฌธ์„œ๋กœ ๋Œ€์ฒดํ•˜์—ฌ ๋™๊ธฐํ™”๋œ SDK ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์˜ ๊ด€๊ณ„๋ฅผ ์ž๋™์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„๋Š” ๋‹จ๋ฐฉํ–ฅ์ด๋ฉฐ ๊ณ ์œ ์„ฑ์ด๋‚˜ ๊ธฐํƒ€ ์™ธ๋ถ€ ํ‚ค ์ œ์•ฝ ์กฐ๊ฑด์„ ์ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์†Œ์Šค ํ•„๋“œ์—์„œ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์™ธ๋ถ€ ๊ฐ’์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ App Services๋Š” ํ™•์ธ๋œ ๊ด€๊ณ„์—์„œ ์ฐธ์กฐ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ

๋‘ ๊ฐœ์˜ ์ปฌ๋ ‰์…˜์ด ์žˆ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์˜ˆ๋กœ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:

  • accounts ์ปฌ๋ ‰์…˜์—๋Š” ๊ฐ๊ฐ ๊ณ ๊ฐ ๊ณ„์ •์„ ์„ค๋ช…ํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

    ๊ณ„์ • ์ปฌ๋ ‰์…˜ ์Šคํ‚ค๋งˆ
    {
    "title": "Account",
    "properties": {
    "_id": { "bsonType": "objectId" },
    "account_id": { "bsonType": "string" },
    "products": {
    "bsonType": "array",
    "items": { "bsonType": "string" }
    },
    ...
    }
    }
  • customers ์ปฌ๋ ‰์…˜์—๋Š” ๊ฐ๊ฐ ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ณ„์ •์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๋‹จ์ผ ๊ณ ๊ฐ์„ ์„ค๋ช…ํ•˜๋Š” ๋ฌธ์„œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. customers ์ปฌ๋ ‰์…˜์˜ ๋ชจ๋“  ๋ฌธ์„œ์—๋Š” ๊ณ ๊ฐ์—๊ฒŒ ์ ์šฉ๋˜๋Š” accounts ์ปฌ๋ ‰์…˜์˜ ๋ชจ๋“  account_id ๊ฐ’์˜ ๋ฐฐ์—ด์ด ํฌํ•จ๋œ accounts ํ•„๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

    ๊ณ ๊ฐ ์ปฌ๋ ‰์…˜ ์Šคํ‚ค๋งˆ
    {
    "title": "Customer",
    "properties": {
    "username": { "bsonType": "string" },
    "accounts": {
    "bsonType": "array",
    "items": { "bsonType": "string" }
    },
    ...
    }
    }

์•ฑ์€ customers ์ปฌ๋ ‰์…˜์—์„œ ์ด ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. accounts ํ•„๋“œ์— ์ €์žฅ๋œ ๊ณ„์ • ID ๊ฐ’ ๋ฐฐ์—ด์—์„œ accounts ์ปฌ๋ ‰์…˜์— ์žˆ๋Š” ๊ฐ ๋ฌธ์„œ์˜ account_id ํ•„๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

{
"accounts": {
"ref": "#/relationship/mongodb-atlas/sample_analytics/accounts",
"foreign_key": "account_id",
"is_list": true
}
}

์ด ๊ด€๊ณ„๊ฐ€ ์ •์˜๋˜๋ฉด App Services๋Š” ํด๋ผ์ด์–ธํŠธ ์ฟผ๋ฆฌ์—์„œ ๊ณ ๊ฐ๊ณผ ํ•ด๋‹น ๊ณ ๊ฐ์˜ ๋ชจ๋“  ๊ณ„์ •์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ด€๊ณ„๊ฐ€ ์—†์œผ๋ฉด ์ฟผ๋ฆฌ๋Š” ์ „์ฒด Account ๊ฐ์ฒด ๋Œ€์‹  account_id ๊ฐ’ ๋ชฉ๋ก๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„์˜ ์นด๋””๋„๋ฆฌํ‹ฐ์— ๋”ฐ๋ผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š” ์™ธ๋ถ€ ๋ฌธ์„œ์˜ ์ˆ˜๊ฐ€ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. App Services๋Š” 'to-one' ๋ฐ 'to-many', ์ด๋ ‡๊ฒŒ ๋‘ ๊ฐ€์ง€ ๊ด€๊ณ„ ์นด๋””๋„๋ฆฌํ‹ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

'to-one' ๊ด€๊ณ„๋Š” ๊ฐ ์†Œ์Šค ๋ฌธ์„œ๋ฅผ ๋‹จ์ผ ๋ฌธ์„œ ๋˜๋Š” ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜์˜ ๋ฌธ์„œ ๋ฐฐ์—ด๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„์— 'to-one' ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ์žˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋ ค๋ฉด is_list๋ฅผ false๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

data_sources/mongodb-atlas/example/pets/relationships.json
{
"owner": {
"ref": "#/relationship/mongodb-atlas/example/people",
"foreign_key": "_id",
"is_list": false
}
}

App Services๋Š” ์†Œ์Šค ๊ฐ’์„ ์ฐธ์กฐ๋œ ๊ฐ์ฒด ๋˜๋Š” SDK ๋ชจ๋ธ์˜ null ๊ฐ’์œผ๋กœ ์ž๋™์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

{
"name": "Pet",
"properties": {
"name": "string",
"owner": "Person"
}
}
{
"name": "Person",
"properties": {
"name": "string"
}
}

'to-many' ๊ด€๊ณ„๋Š” ๊ฐ ์†Œ์Šค ๋ฌธ์„œ๋ฅผ ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜์˜ ๋ฌธ์„œ ๋ชฉ๋ก๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„์— 'to-many' ์นด๋””๋„๋ฆฌํ‹ฐ๊ฐ€ ์žˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋ ค๋ฉด is_list๋ฅผ true๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค:

data_sources/mongodb-atlas/example/people/relationships.json
{
"pets": {
"ref": "#/relationship/mongodb-atlas/example/pets",
"foreign_key": "_id",
"is_list": true
}
}

App Services๋Š” ์†Œ์Šค ๊ฐ’์„ ์ฐธ์กฐ๋œ ๊ฐ์ฒด ๋˜๋Š” SDK ๋ชจ๋ธ์˜ null ๊ฐ’์œผ๋กœ ์ž๋™์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค.

{
"name": "Pet",
"properties": {
"name": "string"
}
}
{
"name": "Person",
"properties": {
"name": "string",
"pets": "Pet[]"
}
}

๋‚ด์žฅ๋œ ๊ฐ์ฒด๋Š” ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜๊ณผ ๊ด€๊ณ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์  ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด์žฅ๋œ ๊ฐ์ฒด์˜ ์†์„ฑ์— ์•ก์„ธ์Šคํ•ฉ๋‹ˆ๋‹ค.

๋‚ด์žฅ๋œ ๊ฐ์ฒด๋Š” ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜์˜ ๊ฐ์ฒด์™€ ๊ด€๊ณ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{
"title": "Person",
"properties": {
"_id": { "bsonType": "objectId" },
"pet": {
"bsonType":"object",
"properties": {
"favoriteToyBrand": { "bsonType": "objectId" }
}
}
// ...additional model properties
}
}

์  ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜๊ณผ ๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ๋‚ด์žฅ๋œ ๊ฐ์ฒด ์†์„ฑ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜ ์„ธ๋ถ€ ์ •๋ณด ๋ฐ ์™ธ๋ถ€ ํ‚ค ํ•„๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{ "pet.favoriteToyBrand":
{
"ref": "#/relationship/mongodb-atlas/example/ToyBrand",
"foreign_key": "_id",
"is_list": false }
}

๋ชฉ๋ก ์†์„ฑ ๋‚ด์— ๋‚ด์žฅ๋œ ๊ฐ์ฒด๋Š” ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜๊ณผ ๊ด€๊ณ„๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{
"title": "Person",
"properties": {
"_id": { "bsonType": "objectId" },
"pets": {
"bsonType":"array",
"items": {
"bsonType": "object",
"properties": {
"favoriteToyBrand": { "bsonType": "objectId" }
}
}
}
// ...additional model properties
}
}

๋ชฉ๋ก์— ํฌํ•จ๋œ ๋‚ด์žฅ๋œ ๊ฐ์ฒด ์†์„ฑ์— ์•ก์„ธ์Šคํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค: field1.[].field2(์˜ˆ: pets.[].favoriteToyBrand). ์—ฌ๊ธฐ์—์„œ ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜ ์„ธ๋ถ€ ์ •๋ณด ๋ฐ ์™ธ๋ถ€ ํ‚ค ํ•„๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒ

์‚ฌ์ „๊ณผ ์„ธํŠธ์— ๋™์ผํ•œ ๊ตฌ๋ฌธ ์‚ฌ์šฉ

์‚ฌ์ „ ๋ฐ ์„ธํŠธ ๋‚ด์—์„œ ๊ด€๊ณ„๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ด์™€ ๋™์ผํ•œ field1.[].field2 ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{
"pets.[].favoriteToyBrand": {
"ref": "#/relationship/mongodb-atlas/example/ToyBrand",
"foreign_key": "_id",
"is_list": false
}
}

์ฐธ๊ณ 

๊ด€๊ณ„ ๋‚ด ๊ธฐ๋ณธ(Primitives) vs ๋ชฉ๋ก, ์‚ฌ์ „ ๋ฐ ์„ธํŠธ

์œ„์˜ ์˜ˆ์—์„œ๋Š” is_list๊ฐ€ false๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ด€๊ณ„ ๋ฌธ์ž์—ด์˜ ๋์— ์žˆ๋Š” ํ•„๋“œ๋Š” ๋ชฉ๋ก์ด ์•„๋‹Œ ๊ธฐ๋ณธ(primitive) ํ•„๋“œ์ž…๋‹ˆ๋‹ค. ๋‚ด์žฅ๋œ ๊ฐ์ฒด๊ฐ€ ๋ชฉ๋ก์— ํฌํ•จ๋˜์–ด ์žˆ์ง€๋งŒ favoriteToyBrand ์†์„ฑ ์ž์ฒด๋Š” ์‚ฌ์ „, ์ง‘ํ•ฉ ๋˜๋Š” ๋ชฉ๋ก์ด ์•„๋‹™๋‹ˆ๋‹ค.

๊ด€๊ณ„๋ฅผ ์ •์˜ํ•  ๋•Œ๋Š” ์ด๋Ÿฌํ•œ ์ œํ•œ ์‚ฌํ•ญ์„ ์—ผ๋‘์— ๋‘์„ธ์š”:

  • ์ฐธ์กฐ ํ•„๋“œ์— ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ํ•ญ๋ชฉ _id

  • ์ฐธ์กฐ ํ•„๋“œ๋Š” required ํ•„๋“œ๊ฐ€ ์•„๋‹ˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์™ธ๋ถ€ ํ‚ค๋Š” ํ•„๋“œ๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ์ปฌ๋ ‰์…˜์˜ _id ํ•„๋“œ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„๋ฅผ ์ •์˜ํ•˜๋ ค๋ฉด ์†Œ์Šค ์ปฌ๋ ‰์…˜๊ณผ ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜ ๋ชจ๋‘์— ๋Œ€ํ•ด ์ •์˜๋œ ์Šคํ‚ค๋งˆ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๋ ค๋ฉด ์Šคํ‚ค๋งˆ ์ ์šฉ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์Šคํ‚ค๋งˆ์™€ ํ•จ๊ป˜ ์—ฐ๊ฒฐ๋œ MongoDB ๋ฐ์ดํ„ฐ ์†Œ์Šค์—์„œ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ๊ด€๊ณ„๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

๊ด€๊ณ„ ์ •์˜๋Š” ์†Œ์Šค ์ปฌ๋ ‰์…˜์˜ ์Šคํ‚ค๋งˆ์— ํฌํ•จ๋œ ํ•„๋“œ๋ฅผ ๋งคํ•‘ํ•˜๊ณ  ์™ธ๋ถ€ ์ปฌ๋ ‰์…˜ ์Šคํ‚ค๋งˆ์— ์žˆ๋Š” ๋™์ผํ•œ ์œ ํ˜•์˜ ํ•„๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

โ†ย ์Šคํ‚ค๋งˆ ์œ ํ˜•