Docs Menu

문서의 배열 업데이트

이 가이드에서는 다음 배열 업데이트 연산자를 사용하여 문서에 포함된 배열을 수정하는 방법을 알아봅니다.

배열 업데이트 연산자 목록은 서버 매뉴얼 문서의 업데이트 연산자를 참조하세요.

위치 연산자는 업데이트할 배열 요소를 지정합니다. 해당 연산자를 사용하여 기준과 일치하는 배열의 첫 번째 요소, 모든 요소 또는 특정 요소에 업데이트를 적용할 수 있습니다.

위치 연산자를 사용하여 배열의 요소를 지정하려면 점 표기법을 사용합니다. 점 표기법은 BSON 객체를 탐색하기 위한 속성 액세스 구문입니다. 자세히 알아보려면 점 표기법을 참조하세요.

쿼리와 일치하는 각 문서의 첫 번째 배열 요소를 업데이트하려면 위치 연산자 $를 사용합니다.

위치 연산자 $는 쿼리와 일치하는 배열을 참조합니다. 이 연산자를 사용하여 중첩 배열을 참조할 수 없습니다. 중첩된 배열에 액세스하려면 필터링된 위치 연산자를 사용하세요.

중요

드라이버가 삽입 문서에서 $를 필드 이름으로 처리하므로 upsert 호출에는 $ 연산자를 사용하지 마세요.

이 예에서는 다음 샘플 문서를 사용하여 일치하는 첫 번째 배열 요소를 업데이트하는 방법을 보여줍니다.

{
_id: ...,
entries: [
{ x: false, y: 1 },
{ x: "hello", y: 100 },
{ x: "goodbye", y: 1000 }
]
}

다음 코드는 쿼리와 일치하는 첫 번째 배열 요소의 값을 증가시키는 방법을 보여줍니다.

쿼리는 x 값이 string 유형인 entries 배열의 요소와 일치합니다. 업데이트는 첫 번째 일치하는 요소에서 y 값을 33만큼 증가시킵니다.

// Query for all elements in entries array where the value of x is a string
const query = { "entries.x": { $type : "string" } };
// On first matched element, increase value of y by 33
const updateDocument = {
$inc: { "entries.$.y": 33 }
};
// Execute the update operation
const result = await myColl.updateOne(query, updateDocument);

업데이트 작업을 실행한 후 문서는 다음과 같이 표시됩니다:

{
_id: ...,
entries: [
{ x: false, y: 1 },
{ x: "hello", y: 133 },
{ x: "goodbye", y: 1000 }
]
}

이 예시에서는 $ 연산자가 업데이트를 적용하는 배열과 일치하는 entries.x 필드를 쿼리에 포함합니다. 업데이트에서 $ 연산자를 사용하는 동안 쿼리에서 entries.x 필드를 생략하면 드라이버가 일치하는 배열을 식별할 수 없으며 다음과 같은 오류가 발생합니다.

MongoServerError: The positional operator did not find the match needed from the query.

쿼리와 일치하는 각 문서의 모든 배열 요소에 대해 업데이트를 수행하려면 모든 위치 연산자 $[](을)를 사용하세요.

이 예시에서는 전화 통화 기록을 설명하는 다음 샘플 문서를 사용하여 일치하는 모든 배열 요소를 업데이트하는 방법을 보여 줍니다.

{
_id: ...,
date: "5/15/2023",
calls: [
{ time: "10:08 AM", caller: "Mom", duration: 67 },
{ time: "04:11 PM", caller: "Dad", duration: 121 },
{ time: "06:36 PM", caller: "Grandpa", duration: 13 }
]
},
{
_id: ...,
date: "5/16/2023",
calls: [
{ time: "11:47 AM", caller: "Mom", duration: 4 },
]
}

다음 코드는 date"5/15/2023"인 문서의 모든 calls 배열 항목에서 duration 필드를 제거하는 방법을 보여줍니다.

// Query for all documents where date is the string "5/15/2023"
const query = { date: "5/15/2023" };
// For each matched document, remove duration field from all entries in calls array
const updateDocument = {
$unset: { "calls.$[].duration": "" }
};
// Execute the update operation
const result = await myColl.updateOne(query, updateDocument);

업데이트 작업을 실행하면 문서가 다음과 같이 표시됩니다:

{
_id: ...,
date: "5/15/2023",
calls: [
{ time: "10:08 AM", caller: "Mom" },
{ time: "04:11 PM", caller: "Dad" },
{ time: "06:36 PM", caller: "Grandpa" }
]
},
{
_id: ...,
date: "5/16/2023",
calls: [
{ time: "11:47 AM", caller: "Mom", duration: 4 },
]
}

쿼리와 일치하는 각 문서의 모든 포함된 배열 요소에 대해 업데이트를 수행하려면 필터링된 위치 연산자 $[<identifier>]를 사용하세요.

필터링된 위치 연산자 $[<identifier>] 는 업데이트 문서에서 일치하는 배열 요소를 지정합니다. 일치시킬 배열 요소를 식별하려면 이 연산자를 arrayFilters 객체의 <identifier> 연산자와 함께 사용합니다.

<identifier> 자리 표시자는 배열 필드의 요소를 나타냅니다. 소문자로 시작하고 영문 및 숫자 문자만 포함하는 <identifier>의 값을 선택해야 합니다.

업데이트 작업에서 필터링된 위치 연산자를 사용할 수 있습니다. 업데이트 작업은 쿼리, 업데이트 문서 및 옵션 객체(선택 사항)를 매개변수로 사용합니다.

다음 단계에서는 업데이트 작업에서 필터링된 위치 연산자를 사용하는 방법을 설명합니다.

  1. 업데이트 문서의 형식은 다음과 같습니다.

    { $<operator>: { "<array>.$[<identifier>].<arrayField>": <updateParameter> } }

    이 업데이트 문서에는 다음과 같은 자리 표시자가 포함되어 있습니다:

    • {0}lt;operator>: 배열 업데이트 연산자

    • <array>: 업데이트할 문서의 배열

    • <identifier>: 필터링된 위치 연산자의 식별자

    • <arrayField>: 업데이트할 <array> 배열 요소의 필드입니다.

    • <updateParameter>: 업데이트를 설명하는 값

  2. arrayFilters 객체에 일치 조건을 추가합니다. 이 객체는 업데이트에 포함할 배열 요소를 지정하는 쿼리 배열입니다. 이 객체를 options 매개 변수로 설정합니다:

    arrayFilters: [
    { "<identifier>.<arrayField1>": <updateParameter1> },
    { "<identifier>.<arrayField2>": <updateParameter2> },
    ...
    ]
  3. 쿼리, 업데이트 문서 및 옵션을 업데이트 메서드에 전달합니다. 다음 샘플 코드는 이러한 매개 변수를 사용하여 updateOne() 메서드를 호출하는 방법을 보여 줍니다:

    await myColl.updateOne(query, updateDocument, options);

이 예에서는 특정 레시피에 대한 쇼핑 목록을 설명하는 다음 샘플 문서를 사용하여 일치하는 특정 배열 요소를 업데이트하는 방법을 보여줍니다:

{
_id: ...,
date: "11/12/2023",
items: [
{ item: "Scallions", quantity: 3, recipe: "Fried rice" },
{ item: "Mangos", quantity: 4, recipe: "Salsa" },
{ item: "Pork shoulder", quantity: 1, recipe: "Fried rice" },
{ item: "Sesame oil", quantity: 1, recipe: "Fried rice" }
]
},
{
_id: ...,
date: "11/20/2023",
items: [
{ item: "Coffee beans", quantity: 1, recipe: "Coffee" }
]
}

"11/12/2023" 장보기 시 조리법에 포함된 구매 항목의 수량을 늘리고 싶다고 가정해 보겠습니다. 항목이 다음 기준을 모두 충족하는 경우 수량을 두 배로 늘리려고 합니다:

  • 항목은 "Fried rice" 조리법에 필요한 재료입니다.

  • 항목 이름에 단어 '"oil"'(이)가 포함되어 있지 않습니다.

일치하는 배열 항목의 quantity 값을 두 배로 늘리려면 다음 코드와 같이 필터링된 위치 연산자를 사용합니다.

// Query for all documents where date is the string "11/12/2023"
const query = { date: "11/12/2023" };
// For each matched document, change the quantity of items to 2
const updateDocument = {
$mul: { "items.$[i].quantity": 2 }
};
// Update only non-oil items used for fried rice
const options = {
arrayFilters: [
{
"i.recipe": "Fried rice",
"i.item": { $not: { $regex: "oil" } },
}
]
};
// Execute the update operation
const result = await myColl.updateOne(query, updateDocument, options);

업데이트에서 기준과 일치하는 항목에 대해 quantity 값에 2를 곱했습니다. "Sesame oil" 항목이 arrayFilters 객체의 기준과 일치하지 않아 업데이트에서 제외되었습니다. 다음 문서에는 이러한 변경 사항이 반영되어 있습니다:

{
_id: ...,
date: "11/12/2023",
items: [
{ item: "Scallions", quantity: 6, recipe: "Fried rice" },
{ item: "Mangos", quantity: 4, recipe: "Salsa" },
{ item: "Pork shoulder", quantity: 2, recipe: "Fried rice" },
{ item: "Sesame oil", quantity: 1, recipe: "Fried rice" }
]
},
{
_id: ...,
date: "11/20/2023",
items: [
{ item: "Coffee beans", quantity: 1, recipe: "Coffee" }
]
}