$ (업데이트)
정의
$
위치
$
연산자는 배열에서 요소의 위치를 명시적으로 지정하지 않고 업데이트할 배열의 요소를 식별합니다.참고
명확화
읽기 작업에서 배열 요소를 프로젝션하거나 반환하려면
$
프로젝션 연산자를 대신 참조하세요.배열의 모든 요소를 업데이트하려면 대신 모든 위치 연산자
$[]
참조하십시오.배열 필터 조건에 일치하는 모든 요소를 업데이트하려면 필터링된 위치 연산자
$[<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>]
를 대신 사용합니다.