$ (update)
정의
$
위치
$
연산자는 배열에서 요소의 위치를 명시적으로 지정하지 않고 업데이트할 배열의 요소를 식별합니다.참고
명확화
읽기 작업에서 배열 요소를 프로젝트하거나 반환하려면
$
프로젝션 연산자를 대신 참조하세요.배열의 모든 요소를 업데이트하려면 대신 모든 위치 연산자
$[]
참조하십시오.배열 필터 조건에 일치하는 모든 요소를 업데이트하려면 필터링된 위치 연산자
$[<identifier>]
를 참조하세요.
호환성
다음 환경에서 호스팅되는 배포에 위치 $
연산자를 사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
구문
위치 $
연산자는 다음과 같은 형태를 가집니다.
{ "<array>.$" : value }
업데이트 작업, 예를 들어 db.collection.updateOne()
과 db.collection.findAndModify()
를 사용할 때
위치
$
연산자는query document
와 일치하는 첫 번째 요소의 자리 표시자 역할을 하며array
필드는query document
의 일부로 반드시 나타나야 합니다.
예를 들면 다음과 같습니다.
db.collection.updateOne( { <array>: value ... }, { <update operator>: { "<array>.$" : value } } )
행동
MongoDB 5.0부터 업데이트 연산자는 문자열 기반 이름이 있는 문서 필드를 사전순으로 처리합니다. 숫자 이름이 있는 필드는 숫자 순서대로 처리됩니다. 자세한 내용은 업데이트 운영자 동작을 참조하십시오.
upsert
삽입 시 삽입된 문서에서 $
가 필드 이름으로 사용되므로, 위치 연산자 $
를 업서트 연산과 함께 사용하지 마세요.
중첩 배열
$
자리 표시자를 대체하는 값이 단일 값이므로, 위치 연산자 $
는 다른 배열 내에 중첩된 배열을 탐색하는 쿼리와 같이 둘 이상의 배열을 탐색하는 쿼리에는 사용할 수 없습니다.
Unsets
$unset
연산자와 함께 사용할 경우 위치 $
연산자는 배열에서 일치하는 요소를 제거하는 대신 null
로 설정합니다.
부정
쿼리가 $not
, $ne
또는 $nin
과 같은 부정 연산자를 사용하여 배열과 일치하는 경우, 위치 연산자를 사용하여 이 배열의 값을 업데이트할 수 없습니다.
그러나 쿼리의 부정 부분이 $elemMatch
표현식 안에 있는 경우 위치 연산자를 사용하여 이 필드를 업데이트 할 수 있습니다.
다중 배열 매치
$
위치 업데이트 연산자는 여러 배열 필드를 필터링할 때 모호하게 작동합니다.
서버는 업데이트 메서드를 실행할 때 먼저 업데이트할 문서를 결정하는 쿼리를 실행합니다. 업데이트가 여러 배열 필드의 문서를 필터링하는 경우에는 이후에 위치 $
업데이트 연산자를 호출할 때 배열의 필수 위치가 업데이트되지 않을 수도 있습니다.
자세한 내용은 예시를 참조하세요.
예시
배열의 값 업데이트
다음 문서를 사용하여 컬렉션 students
를 생성합니다.
db.students.insertMany( [ { "_id" : 1, "grades" : [ 85, 80, 80 ] }, { "_id" : 2, "grades" : [ 88, 90, 92 ] }, { "_id" : 3, "grades" : [ 85, 100, 90 ] } ] )
배열에서 grades
의 값이 80
인 첫 번째 요소를 82
로 업데이트하려고 하는데 배열에서 해당 요소의 위치를 모르는 경우에는 위치 $
연산자를 사용하세요.
중요
배열 필드를 query
문서의 일부로 포함해야 합니다.
db.students.updateOne( { _id: 1, grades: 80 }, { $set: { "grades.$" : 82 } } )
위치 $
연산자는 업데이트 쿼리 문서의 첫 번째 일치 항목에 대한 자리 표시자 역할을 합니다.
작업 후 students
컬렉션에는 다음 문서가 포함됩니다.
{ "_id" : 1, "grades" : [ 85, 82, 80 ] } { "_id" : 2, "grades" : [ 88, 90, 92 ] } { "_id" : 3, "grades" : [ 85, 100, 90 ] }
배열 내 문서 업데이트
위치 $
연산자는 내장된 문서를 포함한 배열을 간편하게 업데이트할 수 있습니다. 위치 $
연산자를 사용하여 $
연산자에 점 표기법을 적용해 내장된 문서의 필드에 액세스할 수 있습니다.
db.collection.updateOne( { <query selector> }, { <update operator>: { "array.$.field" : value } } )
컬렉션의 내장된 문서 요소 students
grades
값이 내장된 문서의 배열인 다음 문서를 고려합니다:
{ _id: 4, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 85, mean: 85, std: 8 } ] }
위치 $
연산자를 사용하여 grade
(이)가 85
(과)와 같다는 조건과 일치하는 첫 번째 배열 요소의 std
필드를 업데이트합니다.
중요
배열 필드를 query
문서의 일부로 포함해야 합니다.
db.students.updateOne( { _id: 4, "grades.grade": 85 }, { $set: { "grades.$.std" : 6 } } )
이후 연산은 문서의 값이 업데이트된 것을 보여줍니다.
{ "_id" : 4, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 }, { "grade" : 85, "mean" : 90, "std" : 6 }, { "grade" : 85, "mean" : 85, "std" : 8 } ] }
여러 필드 일치 조건을 사용하여 내장된 문서 업데이트하기
$
연산자는 $elemMatch
연산자로 지정된 여러 쿼리 기준과 일치하는 첫 번째 배열 요소를 업데이트할 수 있습니다.
students
컬렉션의 문서에서 grades
필드의 값이 내장된 문서들의 배열로 구성된 문서를 고려해보세요.
{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] }
아래 예에서 $
연산자는 grade
필드 값이 90
이하이고 mean
필드 값이 80
초과인 첫 번째 내장된 문서의 std
필드 값을 업데이트합니다.
db.students.updateOne( { _id: 5, grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } } }, { $set: { "grades.$.std" : 6 } } )
이 작업은 기준과 일치하는 첫 번째 내장된 문서, 즉 배열의 두 번째 내장된 문서를 업데이트합니다.
{ _id: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 6 }, { grade: 90, mean: 85, std: 3 } ] }
다중 배열 매치로 업데이트
쿼리에 컬렉션의 문서를 필터링하는 배열 필드가 여러 개 있는 경우 $
위치 업데이트 연산자가 모호하게 작동합니다.
학생 정보 배열이 들어 있는 students_deans_list
컬렉션의 문서를 예로 들어 보겠습니다:
db.students_deans_list.insertMany( [ { _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2020 ] } ] )
다음 예에서 사용자는 activity_ids
, deans_list
, grades
필드를 사용하여 문서를 필터링하고 deans_list
필드의 2021 값을 2022로 업데이트하여 deans_list
필드를 수정하려고 합니다.
db.students_deans_list.updateOne( { activity_ids: 1, grades: 95, deans_list: 2021 }, { $set: { "deans_list.$": 2022 } } )
서버는 위의 updateOne
메서드를 실행할 때 제공된 배열 필드의 값을 사용하여 사용 가능한 문서를 필터링합니다. deans_list
필드가 필터에 사용되지만 $
위치 업데이트 연산자가 배열에서 업데이트할 위치를 결정하는 데 사용하는 필드는 아닙니다.
db.students_deans_list.find( { _id: 8 } )
출력 예시:
{ _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2022 ] }
updateOne
메서드는 2021의 deans_list
필드와 일치했지만 위치 업데이트 연산자 $
는 대신에 2020 값을 2022로 변경했습니다.
여러 배열에서 일치시킬 때 예기치 않은 결과를 방지하려면 필터링된 위치 연산자 $[<identifier>]
를 대신 사용합니다.