문서의 배열 업데이트
개요
이 가이드에서는 다음 배열 업데이트 연산자를 사용하여 문서에 포함된 배열을 수정하는 방법을 알아봅니다.
위치 연산자:
$
모든 위치 연산자:
$[]
필터링된 위치 연산자:
$[<identifier>]
배열 업데이트 연산자 목록은 서버 매뉴얼 문서의 업데이트 연산자를 참조하세요.
배열 요소 지정
위치 연산자는 업데이트할 배열 요소를 지정합니다. 해당 연산자를 사용하여 기준과 일치하는 배열의 첫 번째 요소, 모든 요소 또는 특정 요소에 업데이트를 적용할 수 있습니다.
위치 연산자를 사용하여 배열의 요소를 지정하려면 점 표기법을 사용합니다. 점 표기법은 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>
의 값을 선택해야 합니다.
사용법
업데이트 작업에서 필터링된 위치 연산자를 사용할 수 있습니다. 업데이트 작업은 쿼리, 업데이트 문서 및 옵션 객체(선택 사항)를 매개변수로 사용합니다.
다음 단계에서는 업데이트 작업에서 필터링된 위치 연산자를 사용하는 방법을 설명합니다.
업데이트 문서의 형식은 다음과 같습니다.
{ $<operator>: { "<array>.$[<identifier>].<arrayField>": <updateParameter> } } 이 업데이트 문서에는 다음과 같은 자리 표시자가 포함되어 있습니다:
$<operator>
: 배열 업데이트 연산자<array>
: 업데이트할 문서의 배열<identifier>
: 필터링된 위치 연산자의 식별자입니다.<arrayField>
: 업데이트할<array>
배열 요소의 필드<updateParameter>
: 업데이트를 설명하는 값
arrayFilters
객체에 일치 조건을 추가합니다. 이 객체는 업데이트에 포함할 배열 요소를 지정하는 쿼리 배열입니다. 이 객체를options
매개 변수로 설정합니다:arrayFilters: [ { "<identifier>.<arrayField1>": <updateParameter1> }, { "<identifier>.<arrayField2>": <updateParameter2> }, ... ] 쿼리, 업데이트 문서 및 옵션을 업데이트 메서드에 전달합니다. 다음 샘플 코드는 이러한 매개 변수를 사용하여
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" } ] }