찾기 및 수정
정의
findAndModify
findAndModify
명령은 하나의 문서를 업데이트하고 반환합니다. 기본적으로 반환된 문서에는 업데이트 시 수정된 내용이 포함되지 않습니다. 업데이트에 대한 수정 사항이 있는 문서를 반환하려면new
옵션을 사용합니다.팁
mongosh
에서 이 명령은db.collection.findAndModify()
헬퍼 메서드를 통해서도 실행 수 있습니다.헬퍼 메서드는
mongosh
사용자에게 편리하지만 데이터베이스 명령과 동일한 수준의 정보를 반환하지 못할 수 있습니다. 편의가 필요하지 않거나 추가 리턴 필드가 필요한 경우 데이터베이스 명령을 사용합니다.
호환성
이 명령은 다음 환경에서 호스팅되는 배포에서 사용할 수 있습니다.
MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스
참고
이 명령은 모든 MongoDB Atlas 클러스터에서 지원됩니다. 모든 명령에 대한 Atlas 지원에 관해 자세히 알아보려면 지원되지 않는 명령을 참조하십시오.
MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전
MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전
버전 5.0에서 변경됨
구문
명령은 다음과 같은 구문을 가집니다:
db.runCommand( { findAndModify: <collection-name>, query: <document>, sort: <document>, remove: <boolean>, update: <document or aggregation pipeline>, new: <boolean>, fields: <document>, upsert: <boolean>, bypassDocumentValidation: <boolean>, writeConcern: <document>, maxTimeMS: <integer>, collation: <document>, arrayFilters: <array>, hint: <document|string>, comment: <any>, let: <document> // Added in MongoDB 5.0 } )
명령 필드
이 명령은 다음 필드를 사용합니다.
필드 | 유형 | 설명 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 문서 | 선택 사항. 수정을 위한 선택 기준입니다. 지정하지 않으면 빈 문서로 기본 설정됩니다. 쿼리 인수가 문서가 아닌 경우 작업 오류가 발생합니다. | ||||||||||||||||||
| 문서 | 선택 사항. 쿼리 가 여러 문서를 선택하는 경우 작업을 업데이트할 문서 를 결정합니다. 정렬 인수가 문서가 아닌 경우 작업 오류가 발생합니다. MongoDB는 특정 순서에 따라 문서를 컬렉션에 저장하지 않습니다. 중복 값이 포함된 필드를 정렬할 때 해당 값이 포함된 문서는 임의의 순서로 반환될 수 있습니다. 일관적인 정렬 순서가 필요한 경우 고유값이 포함된 필드를 정렬에 하나 이상 포함하세요. 이를 보장하는 가장 쉬운 방법은 정렬 쿼리에 자세한 내용은 Sort Consistency(정렬 일관성)을(를) 참조하세요. | ||||||||||||||||||
| 부울 |
| ||||||||||||||||||
| 문서 또는 배열 |
| ||||||||||||||||||
| 부울 | 선택 사항. | ||||||||||||||||||
| 문서 | 선택 사항. 반환할 필드의 하위 집합입니다. 필드 인수가 문서가 아니면 작업 오류가 발생합니다. | ||||||||||||||||||
| 부울 | 선택 사항.
업서트가 여러 번 발생하지 않도록 기본값은 | ||||||||||||||||||
| 부울 | 선택 사항. 가 작업 중에 문서 유효성 검사 를 우회하도록 설정합니다. 이를 통해 유효성 검사 요구 사항을 충족하지 않는 문서를 업데이트 할 수 | ||||||||||||||||||
| 문서 | 선택 사항입니다. 쓰기 고려를 표현하는 문서입니다. 기본 쓰기 고려를 사용하지 않으려면 생략하세요. 트랜잭션에서 실행되는 경우 작업에 대한 쓰기 고려를 명시적으로 설정하지 마세요. 트랜잭션에 쓰기 고려를 사용하려면 트랜잭션 및 쓰기 고려를 참조하세요. | ||||||||||||||||||
| non-negative integer | 선택 사항. 시간 제한을 밀리초 단위로 지정합니다. MongoDB는 | ||||||||||||||||||
| 문자열 | 명령을 실행할 collection입니다. | ||||||||||||||||||
| 문서 | 선택 사항. 작업에 사용할 데이터 정렬을 지정합니다. 데이터 정렬을 사용하면 대소문자 및 악센트 표시 규칙과 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다. 데이터 정렬 옵션의 구문은 다음과 같습니다:
데이터 정렬을 지정할 때 데이터 정렬이 지정되지 않았지만 컬렉션에 기본 데이터 정렬이 있는 경우( 컬렉션 또는 연산에 대한 데이터 정렬이 지정되지 않은 경우, MongoDB는 이전 버전에서 문자열 비교에 사용된 간단한 이진 비교를 사용합니다. 한 연산에 대해 여러 데이터 정렬을 지정할 수 없습니다. 예를 들어 필드별로 서로 다른 데이터 정렬을 지정할 수 없으며 정렬과 함께 찾기를 수행하는 경우 찾기 와 정렬에서 각각 다른 데이터 정렬을 사용하는 것은 허용되지 않습니다. | ||||||||||||||||||
| 배열 | 선택 사항입니다. 필터 문서의 배열로, 배열 필드에 대한 업데이트 작업을 위해 수정할 배열 요소를 결정합니다. 업데이트 문서에서
업데이트 문서에 동일한 식별자를 여러 번 포함할 수 있지만, 업데이트 문서의 각 고유 식별자(
그러나 다음 예시와 같이 단일 필터 문서에서 동일한 식별자에 복합 조건을 지정할 수 있습니다.
예제는 를 사용한 배열 업데이트 작업을 참조하세요.
| ||||||||||||||||||
| 문서 또는 문자열 | 선택 사항. 이 옵션은 인덱스 사양 문서 또는 인덱스 이름 문자열을 사용할 수 있습니다. 존재하지 않는 인덱스를 지정하면 연산 오류가 발생합니다. | ||||||||||||||||||
| any | 선택 사항. 이 명령에 첨부할 사용자 제공 코멘트입니다. 설정되면 이 설명은 다음 위치에서 이 명령의 레코드와 함께 표시됩니다.
댓글은 유효한 모든 BSON types (문자열, 정수, 객체, 배열 등)이 될 수 있습니다. | ||||||||||||||||||
문서 | 선택 사항. 변수 목록이 있는 문서를 지정합니다. 이를 통해 쿼리 텍스트에서 변수를 분리하여 명령 가독성을 향상시킬 수 있습니다. 문서 구문은 다음과 같습니다:
변수는 표현식에서 반환된 값으로 설정되며 이후에는 변경할 수 없습니다. 명령에서 변수 값에 액세스하려면 변수를 사용하여 결과를 필터링하려면 및 변수를 사용하는 전체 예시 버전 5.0에 추가. |
출력
findAndModify
명령은 다음 필드가 있는 문서를 반환합니다.
필드 | 유형 | 설명 |
---|---|---|
| 문서 | 명령의 반환값을 포함합니다. 자세한 |
| 문서 | 업데이트된 문서에 대한 정보가 포함되어 있습니다. 자세한 내용은 를 |
| 숫자 | 명령의 실행 상태를 포함합니다. 성공하면 |
lastErrorObject
lastErrorObject
내장된 문서에는 다음 필드가 있습니다.
필드 | 유형 | 설명 |
---|---|---|
| 부울 |
|
| 문서 |
|
value
remove
작업의 경우 쿼리가 문서와 일치하면 value
에 제거된 문서가 포함됩니다. 쿼리가 제거할 문서와 일치하지 않는 경우 value
에는 null
이 포함됩니다.
update
작업의 경우, value
내장된 문서에는 다음 필드가 있습니다.
new
매개변수가 설정되지 않았거나false
인 경우:쿼리가 문서와 일치하면 수정 전 문서가 나타납니다.
그렇지 않으면
null
이(가) 표시됩니다.
new
가true
인 경우:쿼리가 일치하는 항목을 반환하면 업데이트된 문서가 표시됩니다.
upsert: true
(이)면서 쿼리와 일치하는 문서가 없으면 삽입된 문서가 나타납니다.그렇지 않으면
null
이(가) 표시됩니다.
행동
고유 인덱스가 포함된 업서트
중복을 방지하는 고유 인덱스 가 없는 경우 업서트는 중복 문서를 생성할 수 있습니다.
이름이 Andy
인 문서가 없고 여러 클라이언트가 대략 동시에 다음 명령을 실행하는 예시를 가정해 보겠습니다.
db.runCommand( { findAndModify: "people", query: { name: "Andy" }, update: { $inc: { score: 1 } }, upsert: true } )
클라이언트가 데이터를 성공적으로 삽입하기 전에 모든 findAndModify
연산에서 쿼리 단계가 완료되었으며 name
필드에 고유 인덱스가 없는 경우 각 findAndModify
연산에서 삽입이 발생하여 name: Andy
가 포함된 문서가 여러 개 생성될 수 있습니다.
name
필드의 고유 인덱스는 문서가 하나만 생성되도록 합니다. 이 고유 인덱스가 적용되면 이제 여러 findAndModify
연산이 다음과 같은 동작을 나타냅니다.
정확히 하나의
findAndModify
작업으로 새 문서가 성공적으로 삽입됩니다.다른
findAndModify
작업은 새로 삽입된 문서를 업데이트하거나 고유 키 충돌로 인해 실패합니다.다른
findAndModify
작업을 통해 새로 삽입한 문서를 업데이트하려면 다음 조건을 모두 충족해야 합니다.target collection에 중복 키 오류를 일으킬 수 있는 고유 인덱스가 있습니다.
업데이트 작업이
updateMany
이 아니거나multi
이false
입니다.업데이트 일치 조건은 둘 중 하나입니다:
단일 동등성 조건자. 예를 들면 다음과 같습니다.
{ "fieldA" : "valueA" }
동등성 조건자의 논리적 AND. 예를 들면 다음과 같습니다.
{ "fieldA" : "valueA", "fieldB" : "valueB" }
동등성 조건자의 필드는 고유 인덱스 키 패턴의 필드와 일치합니다.
업데이트 작업은 고유 인덱스 키 패턴의 필드를 수정하지 않습니다.
다음 표는 키 충돌이 발생하면 업데이트를 초래하거나 실패하는 upsert
작업의 예를 보여줍니다.
고유 인덱스 키 패턴 | 업데이트 작업 | 결과 | ||||||
---|---|---|---|---|---|---|---|---|
|
| 일치하는 문서의 | ||||||
|
| 고유 인덱스 키 패턴( | ||||||
|
| 동등성 조건자 필드( |
샤드 컬렉션
샤딩된 컬렉션에서 findAndModify
을 사용하려면 다음을 수행합니다.
샤드 1개만을 대상으로 하는 경우
query
필드에 부분 샤드 키를 사용하거나,query
필드의 전체 샤드 키에 대한 동등성 조건을 제공할 수 있습니다.
샤딩된 컬렉션의 문서에는 샤드 키 필드가 누락될 수 있습니다. 샤드 키가 누락된 문서를 대상으로 하려면 null
동등성 매치를 다른 필터 조건(예: _id
필드)과 함께 사용할 수 있습니다. 예를 들면 다음과 같습니다.
{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key
샤드 키 수정
샤드 키 필드가 변경할 수 없는 _id
필드가 아닌 경우 문서의 샤드 키 값을 업데이트할 수 있습니다.
경고
샤딩된 컬렉션의 문서에는 샤드 키 필드가 누락될 수 있습니다. 문서의 샤드 키 값을 변경할 때 실수로 샤드 키를 제거하지 않도록 주의해야 합니다.
기존 샤드 키 값을 findAndModify
로 업데이트하려면 다음을 수행합니다.
누락된 샤드 키
샤딩된 컬렉션의 문서에는 샤드 키 필드가 누락될 수 있습니다. findAndModify
를 사용하여 문서의 누락된 샤드 키를 설정하려면 다음을 수행해야 합니다.
반드시
mongos
에서 실행해야 합니다. 샤드에서 직접 작업을 실행하지 않아야 합니다.전체 샤드 키에 동등성 필터를 포함시켜야 합니다.
팁
누락된 키 값은 null 동등성 매치의 일부로 반환되므로 null 값 키가 업데이트되지 않도록 하려면 추가 쿼리 조건(예: _id
필드)을 적절히 포함하세요.
다음도 참조하세요.
문서 유효성 검사
findAndModify
명령은 유효성 검사 규칙이 있는 컬렉션에 문서를 삽입하거나 업데이트할 때 문서 유효성 검사를 무시할 수 있는 bypassDocumentValidation
옵션에 대한 지원을 추가합니다.
update
메서드와 비교
문서를 업데이트할 때 findAndModify
메서드와 updateOne()
메서드는 다음과 같이 서로 다르게 작동합니다.
여러 문서가 업데이트 기준과 일치하는 경우
findAndModify
에sort
를 지정하여 업데이트할 문서에 제어 수단을 제공할 수 있습니다.updateOne()
일치하는 첫 번째 문서를 업데이트합니다.기본적으로
findAndModify
는 문서의 사전 수정된 버전과 작업 상태가 포함된 객체를 반환합니다. 업데이트된 문서를 얻으려면new
옵션을 사용하세요.updateOne()
메서드는 연산의 상태가 포함된WriteResult()
객체를 반환합니다.업데이트된 문서를 반환하려면
find()
메서드를 사용하세요. 그러나 업데이트와 문서 검색 사이에 다른 업데이트로 인해 문서가 수정되었을 수 있습니다. 게다가 해당 업데이트로 인해 문서가 1개만 수정되었으나 여러 문서가 일치한 경우, 업데이트된 문서를 식별하기 위해서는 추가 로직을 사용해야 합니다.
단일 문서를 수정할 때는 findAndModify
메서드 및 updateOne()
메서드 둘 다 문서를 원자 단위로 업데이트합니다. 이 메서드들의 상호작용과 연산 순서에 대한 자세한 내용은 원자성 및 트랜잭션을 참조하세요.
트랜잭션
findAndModify
는 분산 트랜잭션 내에서 사용할 수 있습니다.
중요
대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.
추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.
트랜잭션 내 업서트
트랜잭션이 교차 샤드 쓰기 트랜잭션(write transaction)이 아닌 경우 분산 트랜잭션 내에서 컬렉션과 인덱스를 생성할 수 있습니다.
upsert: true
인 findAndModify
는 기존 컬렉션이나 존재하지 않는 컬렉션에서 실행될 수 있습니다. 존재하지 않는 컬렉션에서 실행하면 작업이 컬렉션을 만듭니다.
쓰기 고려 및 트랜잭션
트랜잭션에서 실행되는 경우 작업에 대한 쓰기 고려를 명시적으로 설정하지 마세요. 트랜잭션에 쓰기 고려를 사용하려면 트랜잭션 및 쓰기 고려를 참조하세요.
예시
업데이트 및 반환
다음 명령은 문서가 query
기준과 일치하는 people
collection의 기존 문서를 업데이트합니다.
db.runCommand( { findAndModify: "people", query: { name: "Tom", state: "active", rating: { $gt: 10 } }, sort: { rating: 1 }, update: { $inc: { score: 1 } } } )
이 명령은 다음 조치를 수행합니다.
query
은(는)name
필드의 값이Tom
(이)고,state
필드의 값이active
(이)고,rating
필드의 값이 10greater than
인people
컬렉션에서 문서를 찾습니다.sort
는 쿼리 결과를 오름차순으로 정렬합니다. 여러 문서가query
조건을 충족하는 경우 명령은 이sort
에 의해 정렬된 첫 번째 문서를 수정하기 위해 선택합니다.update
increments
score
필드 값에 1을 곱합니다.이 명령은 다음 필드가 있는 문서를 반환합니다.
true
인updatedExisting
필드를 포함하여 명령의 세부정보가 포함된lastErrorObject
필드 및원본(예: 수정 전) 문서가 포함된
value
필드가 이 업데이트에 선택되었습니다.{ "lastErrorObject" : { "connectionId" : 1, "updatedExisting" : true, "n" : 1, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1 }, value" : { "_id" : ObjectId("54f62d2885e4be1f982b9c9c"), "name" : "Tom", "state" : "active", "rating" : 100, "score" : 5 }, "ok" : 1 }
value
필드에 업데이트된 문서를 반환하려면 new:true
옵션을 명령에 추가합니다.
query
조건과 일치하는 문서가 없는 경우 명령은 value
필드에 null
이 포함된 문서를 반환합니다.
{ "value" : null, "ok" : 1 }
mongosh
및 많은 드라이버는 findAndModify()
헬퍼 메서드를 제공합니다. 셸 헬퍼를 사용하면 이 이전 작업은 다음과 같은 형식을 취할 수 있습니다.
db.people.findAndModify( { query: { name: "Tom", state: "active", rating: { $gt: 10 } }, sort: { rating: 1 }, update: { $inc: { score: 1 } } } );
그러나 findAndModify()
shell helper 메서드는 수정되지 않은 문서만 반환하거나 new
이 true
인 경우 업데이트된 문서만 반환합니다.
{ "_id" : ObjectId("54f62d2885e4be1f982b9c9c"), "name" : "Tom", "state" : "active", "rating" : 100, "score" : 5 }
upsert: true
다음 findAndModify
명령에는 일치하는 문서를 업데이트하거나, 일치하는 문서가 없는 경우 새 문서를 만드는 update
작업용 upsert:
true
옵션이 포함되어 있습니다.
db.runCommand( { findAndModify: "people", query: { name: "Gus", state: "active", rating: 100 }, sort: { rating: 1 }, update: { $inc: { score: 1 } }, upsert: true } )
명령이 일치하는 문서를 찾으면 업데이트를 수행합니다.
명령이 일치하는 문서를 찾지 못하면 upsert: true 작업이 포함된 update
는 삽입이 수행되고 다음 필드가 있는 문서가 반환됩니다.
새로 삽입된 문서의
_id
값을 포함하는 필드upserted
를 포함하여 명령의 세부 정보를 포함하는lastErrorObject
필드 및null
이 포함된value
필드입니다.
{ "value" : null, "lastErrorObject" : { "updatedExisting" : false, "n" : 1, "upserted" : ObjectId("54f62c8bc85d4472eadea26f") }, "ok" : 1 }
새 문서 반환하기
다음 findAndModify
명령에는 upsert: true
옵션과 new:true
옵션이 모두 포함되어 있습니다. 이 명령은 일치하는 문서를 업데이트하고 업데이트된 문서를 반환하거나, 일치하는 문서가 없으면 문서를 삽입하고 value
필드에 새로 삽입된 문서를 반환합니다.
다음 예시에서는 people
컬렉션의 어떤 문서도 query
조건과 일치하지 않습니다.
db.runCommand( { findAndModify: "people", query: { name: "Pascal", state: "active", rating: 25 }, sort: { rating: 1 }, update: { $inc: { score: 1 } }, upsert: true, new: true } )
이 명령은 value
필드에 새로 삽입된 문서를 반환합니다.
{ "lastErrorObject" : { "connectionId" : 1, "updatedExisting" : false, "upserted" : ObjectId("54f62bbfc85d4472eadea26d"), "n" : 1, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1 }, "value" : { "_id" : ObjectId("54f62bbfc85d4472eadea26d"), "name" : "Pascal", "rating" : 25, "state" : "active", "score" : 1 }, "ok" : 1 }
정렬 및 제거
다음 예시에서는 rating
필드에 sort
사양을 포함시킴으로써, state
값이 active
(이)면서 일치하는 문서 중 rating
값이 가장 낮은 단일 문서를 people
컬렉션에서 제거합니다.
db.runCommand( { findAndModify: "people", query: { state: "active" }, sort: { rating: 1 }, remove: true } )
이 명령은 삭제된 문서를 반환합니다.
{ "lastErrorObject" : { "connectionId" : 1, "n" : 1, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1 }, "value" : { "_id" : ObjectId("54f62a6785e4be1f982b9c9b"), "name" : "XYZ123", "score" : 1, "state" : "active", "rating" : 3 }, "ok" : 1 }
데이터 정렬 지정
데이터 정렬을 사용하면 대소문자 및 악센트 표시 규칙과 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다.
컬렉션 myColl
에는 다음 문서가 있습니다.
{ _id: 1, category: "café", status: "A" } { _id: 2, category: "cafe", status: "a" } { _id: 3, category: "cafE", status: "a" }
다음 작업에는 데이터 정렬 옵션이 포함됩니다.
db.runCommand( { findAndModify: "myColl", query: { category: "cafe", status: "a" }, sort: { category: 1 }, update: { $set: { status: "Updated" } }, collation: { locale: "fr", strength: 1 } } )
연산은 다음 문서를 반환합니다.
{ "lastErrorObject" : { "updatedExisting" : true, "n" : 1 }, "value" : { "_id" : 1, "category" : "café", "status" : "A" }, "ok" : 1 }
다음 값을 이용한 배열 업데이트 연산 arrayFilters
참고
arrayFilters
은 집계 파이프라인을 사용하는 업데이트에는 사용할 수 없습니다.
배열 필드를 업데이트할 때 업데이트할 배열 요소를 결정하는 arrayFilters
를 지정할 수 있습니다.
업데이트 요소가 arrayFilters
기준과 일치함
참고
arrayFilters
은 집계 파이프라인을 사용하는 업데이트에는 사용할 수 없습니다.
다음 문서를 사용하여 컬렉션 students
를 생성합니다.
db.students.insertMany( [ { "_id" : 1, "grades" : [ 95, 92, 90 ] }, { "_id" : 2, "grades" : [ 98, 100, 102 ] }, { "_id" : 3, "grades" : [ 95, 110, 100 ] } ] )
grades
배열에서 100
이상인 모든 요소를 업데이트하려면 위치 $[<identifier>]
연산자를 arrayFilters
옵션과 함께 사용합니다.
db.runCommand( { findAndModify: "students", query: { grades: { $gte: 100 } }, update: { $set: { "grades.$[element]" : 100 } }, arrayFilters: [ { "element": { $gte: 100 } } ] } )
이 연산은 단일 문서의 grades
필드를 업데이트합니다. 연산이 완료된 후 컬렉션에 포함되는 문서는 다음과 같습니다.
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 100 ] } { "_id" : 3, "grades" : [ 95, 110, 100 ] }
문서 배열의 특정 요소 업데이트
참고
arrayFilters
은 집계 파이프라인을 사용하는 업데이트에는 사용할 수 없습니다.
다음 문서를 사용하여 컬렉션 students2
를 생성합니다.
db.students2.insertMany( [ { "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" : 85, "std" : 6 } ] }, { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85, "std" : 4 } ] } ] )
다음 작업은 필드가 인 문서를 찾고 _id
1
필터링된 위치 연산자 를 와 함께 $[<identifier>]
사용하여 arrayFilters
mean
grades
등급이 더 높은 배열의 모든 요소에 대해 를 85
업데이트합니다. 이상입니다.
db.runCommand( { findAndModify: "students2", query: { _id : 1 }, update: { $set: { "grades.$[elem].mean" : 100 } }, arrayFilters: [ { "elem.grade": { $gte: 85 } } ] } )
이 연산은 단일 문서의 grades
필드를 업데이트합니다. 연산이 완료된 후 컬렉션에 포함되는 문서는 다음과 같습니다.
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 6 } ] } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85, "std" : 4 } ] }
업데이트에 집계 파이프라인 사용하기
findAndModify
업데이트를 위한 집계 파이프라인을 수락할 수 있습니다. 파이프라인은 다음 단계로 구성될 수 있습니다.
$addFields
및 그 별칭$set
$replaceRoot
및 별칭$replaceWith
입니다.
집계 파이프라인e을 사용하면 현재 필드 값을 기반으로 조건부 업데이트를 표현하거나 다른 필드의 값을 사용하여 한 필드를 업데이트하는 등 보다 표현력이 풍부한 업데이트 구문을 작성할 수 있습니다.
그 예로 다음 문서를 사용해 students2
컬렉션을 생성하세요.
db.students2.insertMany( [ { "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" : 85, "std" : 6 } ] }, { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85, "std" : 4 } ] } ] )
다음 연산은 _id
필드가 1
인 문서를 찾고, 집계 파이프라인을 사용하여 grades
필드에서 새 필드 total
을(를) 계산합니다.
db.runCommand( { findAndModify: "students2", query: { "_id" : 1 }, update: [ { $set: { "total" : { $sum: "$grades.grade" } } } ], new: true } )
작업 후 컬렉션에는 다음 문서가 포함됩니다.
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" :85, "std" : 6 } ], "total" : 250 } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85,"std" : 4 } ] }
findAndModify
작업에 대한 hint
지정
mongosh
에서 다음 문서를 사용하여 members
컬렉션을 생성하세요.
db.members.insertMany( [ { "_id" : 1, "member" : "abc123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }, { "_id" : 3, "member" : "lmn123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 4, "member" : "pqr123", "status" : "D", "points" : 20, "misc1" : "Deactivated", "misc2" : null }, { "_id" : 5, "member" : "ijk123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null }, { "_id" : 6, "member" : "cde123", "status" : "A", "points" : 86, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" } ] )
컬렉션에 다음 인덱스를 만듭니다.
db.members.createIndex( { status: 1 } ) db.members.createIndex( { points: 1 } )
다음 작업은 인덱스 { status: 1 }
을 사용하도록 명시적으로 암시합니다.
db.runCommand({ findAndModify: "members", query: { "points": { $lte: 20 }, "status": "P" }, remove: true, hint: { status: 1 } })
참고
존재하지 않는 인덱스를 지정하면 연산 오류가 발생합니다.
사용된 인덱스를 보려면 작업에 대해 explain
을 실행하세요.
db.runCommand( { explain: { findAndModify: "members", query: { "points": { $lte: 20 }, "status": "P" }, remove: true, hint: { status: 1 } }, verbosity: "queryPlanner" } )
에서 변수 사용 let
버전 5.0에 추가.
명령의 다른 곳에서 액세스할 수 있는 변수를 정의하려면 let 옵션을 사용합니다.
참고
변수를 사용하여 결과를 필터링하려면 $expr
연산자 내에서 변수에 액세스해야 합니다.
컬렉션 cakeFlavors
을 만듭니다:
db.cakeFlavors.insertMany( [ { _id: 1, flavor: "chocolate" }, { _id: 2, flavor: "strawberry" }, { _id: 3, flavor: "cherry" } ] )
다음 예시에서는 let
의 targetFlavor
변수를 정의하고, 이 변수를 사용하여 케이크 맛을 체리에서 오렌지로 변경합니다.
db.cakeFlavors.runCommand( { findAndModify: db.cakeFlavors.getName(), query: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } }, update: { flavor: "orange" }, let: { targetFlavor: "cherry" } } )