Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ / /

db.collection.findAndModify()

이 페이지의 내용

  • 정의
  • 호환성
  • 구문
  • 데이터 반환하기
  • 행동
  • 예시

드라이버가 포함된 MongoDB

이 페이지에서는 mongosh 메서드를 설명합니다. MongoDB 드라이버에서 해당 메서드를 보려면 프로그래밍 언어의 해당 페이지를 참조하세요.

C#Java SyncNode.jsPyMongoCC++GoJava RSKotlin CoroutineKotlin SyncPHPMongoidRustScala
db.collection.findAndModify(document)

중요

더 이상 사용되지 않는 mongosh 메서드

단일 문서를 업데이트하고 반환합니다. 반환된 문서에는 기본적으로 업데이트 시 수정된 내용이 포함되지 않습니다. 업데이트에 대한 수정 사항이 있는 문서를 반환하려면 new 옵션을 사용합니다.

이 메서드는 다음 환경에서 호스팅되는 배포에서 사용할 수 있습니다.

  • MongoDB Atlas: 클라우드에서의 MongoDB 배포를 위한 완전 관리형 서비스

참고

이 명령은 모든 MongoDB Atlas 클러스터에서 지원됩니다. 모든 명령에 대한 Atlas 지원 에 대한 자세한 내용은 지원되지 않는 명령을 참조하세요.

버전 5.0에서 변경됨

findAndModify() 메서드의 형식은 다음과 같습니다.

db.collection.findAndModify({
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: [ <filterdocument1>, ... ],
let: <document> // Added in MongoDB 5.0
});

db.collection.findAndModify() 메서드는 다음의 내장된 문서 필드로 문서 매개 변수를 사용합니다.

Parameter
유형
설명
query
문서

선택 사항입니다. 수정의 선택 기준입니다. query 필드는 db.collection.find() 메서드에 사용된 것과 동일한 쿼리 선택기를 사용합니다. 쿼리가 여러 문서와 일치할 수도 있지만 db.collection.findAndModify()수정할 문서를 하나만 선택합니다.

지정하지 않으면 빈 문서로 기본 설정됩니다.

쿼리 인수가 문서가 아닌 경우 작업 오류가 발생합니다.

sort

문서

선택 사항입니다. 쿼리가 여러 문서를 선택하는 경우 연산이 업데이트할 문서를 결정합니다. db.collection.findAndModify()는 이 인수로 지정된 정렬 순서대로 첫 번째 문서를 업데이트합니다.

정렬 인수가 문서가 아닌 경우 작업 오류가 발생합니다.

MongoDB는 특정 순서에 따라 문서를 컬렉션에 저장하지 않습니다. 중복 값이 포함된 필드를 정렬할 때 해당 값이 포함된 문서는 임의의 순서로 반환될 수 있습니다.

일관적인 정렬 순서가 필요한 경우 고유값이 포함된 필드를 정렬에 하나 이상 포함하세요. 이를 보장하는 가장 쉬운 방법은 정렬 쿼리에 _id 필드를 포함하는 것입니다.

자세한 내용은 Sort Consistency(정렬 일관성)을(를) 참조하세요.

remove
부울
remove 또는 update 필드 중 1개를 지정해야 합니다. query 필드에 지정된 문서를 제거합니다. 선택된 문서를 제거하려면 이 값을 true(으)로 설정하세요. 기본값은 false입니다.
update
문서 또는 배열

remove 또는 update 필드 중 1개를 지정해야 합니다. 선택된 문서의 업데이트를 실행합니다.

new
부울
선택 사항. true 인 경우 원본이 아닌 업데이트된 문서를 반환합니다. 기본값은 false 입니다.
fields
문서

선택 사항입니다. 반환할 필드의 하위 세트입니다. fields 문서는 fields: { <field1>: 1, <field2>: 1, ... }대로 값이 1인 필드를 포함하도록 지정합니다.

fields 인수가 문서가 아닌 경우 작업 오류가 발생합니다.

프로젝션에 대한 자세한 내용이 필요하시면 fields 프로젝션을 참조하세요.

upsert
부울

선택 사항. update 필드와 함께 사용합니다.

true인 경우 findAndModify()는 다음 작업 중 한 가지를 실행합니다.

  • 0}과 일치하는 문서가 없는 query 경우 새 문서를 만듭니다. 자세한 내용은 upsert 동작을 참조하세요.

  • query와 일치하는 단일 문서를 업데이트합니다.

업서트가 여러 번 발생하지 않도록 하려면 query 필드를 고유하게 인덱싱해야 합니다. 예시를 보려면 고유 인덱스로 업서트를 참조하세요.

기본값은 false이며, 일치하는 문서를 찾을 수 없을 때 새 문서를 삽입하지 않습니다.

bypassDocumentValidation
부울
선택 사항입니다. 작업 중에 db.collection.findAndModify()가 문서 유효성 검사를 우회하도록 설정합니다. 이를 통해 유효성 검사 요구 사항을 충족하지 않는 문서를 업데이트할 수 있습니다.
writeConcern
문서

선택 사항입니다. 쓰기 고려를 표현하는 문서입니다. 기본 쓰기 고려를 사용하지 않으려면 생략하세요.

트랜잭션에서 실행되는 경우 작업에 대한 쓰기 고려를 명시적으로 설정하지 마세요. 트랜잭션에 쓰기 고려를 사용하려면 트랜잭션 및 쓰기 고려를 참조하세요.

maxTimeMS
non-negative integer

선택 사항.

시간 제한을 밀리초 단위로 지정합니다. maxTimeMS에 값을 지정하지 않으면 작업이 시간 초과되지 않습니다. 0 값은 바인딩되지 않는 기본 동작을 명시적으로 지정합니다.

MongoDB는 db.killOp()와 동일한 메커니즘을 사용하여 할당된 시간 제한을 초과하는 작업을 종료합니다. MongoDB는 지정된 중단 지점 중 하나에서만 작업을 종료합니다.

collation
문서

선택 사항.

작업에 사용할 데이터 정렬을 지정합니다.

데이터 정렬을 사용하면 대소문자 및 악센트 표시 규칙과 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다.

데이터 정렬 옵션의 구문은 다음과 같습니다:

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

데이터 정렬을 지정할 때 locale 필드는 필수이고, 다른 데이터 정렬 필드는 모두 선택 사항입니다. 필드에 대한 설명은 데이터 정렬 문서를 참조하세요.

데이터 정렬이 지정되지 않았지만 컬렉션에 기본 데이터 정렬이 있는 경우( db.createCollection() 참조), 작업은 컬렉션에 지정된 데이터 정렬을 사용합니다.

컬렉션 또는 연산에 대한 데이터 정렬이 지정되지 않은 경우, MongoDB는 이전 버전에서 문자열 비교에 사용된 간단한 이진 비교를 사용합니다.

한 연산에 대해 여러 데이터 정렬을 지정할 수 없습니다. 예를 들어 필드별로 서로 다른 데이터 정렬을 지정할 수 없으며 정렬과 함께 찾기를 수행하는 경우 찾기 와 정렬에서 각각 다른 데이터 정렬을 사용하는 것은 허용되지 않습니다.

arrayFilters
배열

선택 사항입니다. 필터 문서의 배열로, 배열 필드에 대한 업데이트 작업을 위해 수정할 배열 요소를 결정합니다.

업데이트 문서에서 $[<identifier>] 필터링된 위치 연산자를 사용하여 식별자를 정의한 다음 배열 필터 문서에서 이를 참조합니다. 식별자가 업데이트 문서에 포함되어 있지 않으면 식별자에 대한 배열 필터 문서를 가질 수 없습니다.

<identifier>는 소문자로 시작해야 하며 영숫자만 포함할 수 있습니다.

업데이트 문서에 동일한 식별자를 여러 번 포함할 수 있지만, 업데이트 문서의 각 고유 식별자($[identifier])에 대해 해당하는 배열 필터 문서를 정확히 하나씩 지정해야 합니다. 즉, 동일한 식별자에 대해 여러 개의 배열 필터 문서를 지정할 수 없습니다. 예를 들어, 업데이트 문에 식별자 x가 포함된 경우(여러 번), x에 대한 별도의 필터 문서 2개가 포함된 arrayFilters에 대해 다음을 지정할 수 없습니다.

// INVALID
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
]

그러나 다음 예시와 같이 단일 필터 문서에서 동일한 식별자에 복합 조건을 지정할 수 있습니다.

// Example 1
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 2
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
// Example 3
[
{ "x.a": { $gt: 85 }, "x.b": { $gt: 80 } }
]

예시는 배열 업데이트 연산에 arrayFilters 지정하기를 참조하세요.

arrayFilters 은 집계 파이프라인을 사용하는 업데이트에는 사용할 수 없습니다.

문서

선택 사항.

변수 목록이 있는 문서를 지정합니다. 이를 통해 쿼리 텍스트에서 변수를 분리하여 명령 가독성을 향상시킬 수 있습니다.

문서 구문은 다음과 같습니다:

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

변수는 표현식에서 반환된 값으로 설정되며 이후에는 변경할 수 없습니다.

명령에서 변수 값에 액세스하려면 $$<variable_name> 형식의 이중 달러 기호 접두사 ($$) 를 변수 이름과 함께 사용하십시오.예시: $$targetTotal.

변수를 사용하여 결과를 필터링하려면 $expr 연산자 내에서 변수에 액세스해야 합니다.

let 및 변수를 사용한 전체 예시는 let에서 변수 사용을 참조하세요.

버전 5.0에 추가.

제거 연산에서 쿼리가 문서와 일치하면 findAndModify()이(가) 제거된 문서를 반환합니다. 쿼리가 제거할 문서와 일치하지 않으면 findAndModify()이(가) null(을)를 반환합니다.

업데이트 연산에서 findAndModify()는 다음 중 한 가지를 반환합니다.

  • new 매개변수가 설정되지 않았거나 false인 경우:

    • 쿼리가 문서와 일치하면 수정 전 문서가 나타납니다.

    • 그렇지 않으면 null이(가) 표시됩니다.

  • newtrue인 경우:

    • 쿼리가 일치하는 항목을 반환하면 업데이트된 문서가 표시됩니다.

    • upsert: true(이)면서 쿼리와 일치하는 문서가 없으면 삽입된 문서가 나타납니다.

    • 그렇지 않으면 null이(가) 표시됩니다.

재시도 가능한 쓰기는 findAndModify() 메서드를 필요로 하며 업데이트를 수행하기 전에 복제본 세트의 각 노드에 대해 전체 문서를 특수 사이드 컬렉션으로 복사합니다. 이로 인해 대용량 문서나 대규모 복제 세트를 처리할 때 findAndModify() 작업에 많은 비용이 들 수 있습니다.

8.0 버전의 새로운 기능: 사용자 정의 정렬에서 첫 번째 문서를 더 나은 성능으로 업데이트하려면 sort 옵션과 함께 db.collection.updateOne() 메서드를 사용하세요.

중요

언어 일관성

find()findAndModify() 프로젝션을 집계의 $project 단계와 일치시키는 작업의 일환으로,

fields 옵션에서는 다음 형식의 문서를 사용합니다.

{ field1: <value>, field2: <value> ... }
프로젝션
설명
<field>: <1 or true>
필드 포함 여부를 지정합니다. 프로젝션 값에 0이 아닌 정수를 지정하면 연산은 해당 값을 true로 취급합니다.
<field>: <0 or false>
필드 제외 여부를 지정합니다.
"<field>.$": <1 or true>

$ 배열 프로젝션 연산자를 사용하여 배열 필드의 쿼리 조건과 일치하는 첫 번째 요소를 반환합니다. 프로젝션 값에 대해 0이 아닌 정수를 지정하면 연산은 값을 true로 처리합니다.

에는 사용할 수 없습니다.

<field>: <array projection>

배열 프로젝션 연산자($elemMatch, $slice)를 사용하여 포함할 배열 요소를 지정합니다.

에는 사용할 수 없습니다.

<field>: <aggregation expression>

프로젝션된 필드의 값을 지정합니다.

리터럴 및 집계 변수 사용을 포함한 집계 식 및 구문을 사용하면 새 필드를 프로젝션하거나 기존 필드를 새 값으로 프로젝션할 수 있습니다.

  • 프로젝션 값에 숫자가 아니면서 부울이 아닌 리터럴(예시: 리터럴 문자열, 배열 또는 연산자 표현식)을 지정하면 필드가 새 값으로 프로젝션됩니다.

    • { field: [ 1, 2, 3, "$someExistingField" ] }

    • { field: "New String Value" }

    • { field: { status: "Active", total: { $sum: "$existingArray" } } }

  • 필드의 리터럴 값을 프로젝션하려면 다음 예시와 같은 $literal 집계 표현식을 사용하세요.

    • { field: { $literal: 5 } }

    • { field: { $literal: true } }

    • { field: { $literal: { fieldWithValue0: 0, fieldWithValue1: 1 } } }

내장된 문서의 필드에 대해서는 다음 둘 중 하나를 사용하여 필드를 지정할 수 있습니다.

  • 점 표기법(예시: "field.nestedfield": <value>

  • 중첩된 양식, 예를 들어 { field: { nestedfield: <value> } }

필드를 표시하지 않기 위해 프로젝션에서 _id: 0을 명시적으로 지정하지 않는 한 _id 필드는 기본적으로 반환된 문서에 포함됩니다.

projection 필드는 포함과 제외 사양을 모두 포함할 수 없습니다. 단, _id 필드는 예외입니다.

  • 필드를 명시적으로 포함하는 프로젝션에서 _id 필드는 명시적으로 제외할 수 있는 유일한 필드입니다.

  • 필드를 명시적으로 제외하는 프로젝션에서는 _id 필드가 명시적으로 포함할 수 있는 유일한 필드이지만, _id 필드는 기본적으로 포함됩니다.

프로젝션에 대한 자세한 내용은 다음 섹션도 같이 참조하세요.

중복을 방지하는 고유 인덱스 가 없는 경우 업서트는 중복 문서를 생성할 수 있습니다.

이름이 Andy인 문서가 없고 여러 클라이언트가 대략 동시에 다음 명령을 실행하는 예시를 가정해 보겠습니다.

db.people.findAndModify(
{
query: { name: "Andy" },
update: { $inc: { score: 1 } },
upsert: true
}
)

클라이언트가 데이터를 성공적으로 삽입하기 전에 모든 findOneAndUpdate() 작업이 쿼리 단계를 완료 하고 name 필드에 고유 인덱스가 없는 경우, findOneAndUpdate() 작업마다 삽입이 발생하여 name: Andy 이 포함된 여러 문서가 생성될 수 있습니다.

name 필드에 대한 고유 인덱스는 하나의 문서만 생성되도록 합니다. 고유 인덱스가 적용되면 이제 여러 findOneAndUpdate() 작업에서 다음과 같은 동작이 발생합니다.

  • findOneAndUpdate()번의 연산을 정확히 한 번 실행하면 새 문서를 삽입할 수 있습니다.

  • 다른 findOneAndUpdate() 작업은 새로 삽입된 문서를 업데이트하거나 고유 키 충돌로 인해 실패합니다.

    다른 findOneAndUpdate() 작업에서 새로 삽입된 문서를 업데이트하려면 다음 조건이 모두 충족되어야 합니다.

    • target collection에 중복 키 오류를 일으킬 수 있는 고유 인덱스가 있습니다.

    • 업데이트 작업이 updateMany 이 아니거나 multifalse 입니다.

    • 업데이트 일치 조건은 둘 중 하나입니다:

      • 단일 동등성 조건자. 예를 들면 다음과 같습니다. { "fieldA" : "valueA" }

      • 동등성 조건자의 논리적 AND. 예를 들면 다음과 같습니다. { "fieldA" : "valueA", "fieldB" : "valueB" }

    • 동등성 조건자의 필드는 고유 인덱스 키 패턴의 필드와 일치합니다.

    • 업데이트 작업은 고유 인덱스 키 패턴의 필드를 수정하지 않습니다.

다음 표는 키 충돌이 발생하면 업데이트를 초래하거나 실패하는 upsert 작업의 예를 보여줍니다.

고유 인덱스 키 패턴
업데이트 작업
결과
{ name : 1 }
db.people.updateOne(
{ name: "Andy" },
{ $inc: { score: 1 } },
{ upsert: true }
)
일치하는 문서의 score 필드가 1씩 증가합니다.
{ name : 1 }
db.people.updateOne(
{ name: { $ne: "Joe" } },
{ $set: { name: "Andy" } },
{ upsert: true }
)
고유 인덱스 키 패턴(name)의 필드를 수정하기 때문에 작업이 실패합니다.
{ name : 1 }
db.people.updateOne(
{ name: "Andy", email: "andy@xyz.com" },
{ $set: { active: false } },
{ upsert: true }
)
동등성 조건자 필드(name, email)가 인덱스 키 필드(name)와 일치하지 않기 때문에 작업이 실패합니다.

샤드 컬렉션에서 findAndModify을(를) 사용하려면 다음 방법대로 하세요.

  • 샤드 1개만을 대상으로 하는 경우 query 필드에 부분 샤드 키를 사용하거나,

  • query 필드의 전체 샤드 키에 대한 동등성 조건을 제공할 수 있습니다.

  • 버전 7.1부터는 쿼리 사양에서 샤드 키_id 필드를 제공할 필요가 없습니다.

샤딩된 컬렉션의 문서에는 샤드 키 필드가 누락될 수 있습니다. 샤드 키가 누락된 문서를 대상으로 하려면 null 동등성 매치를 다른 필터 조건(예: _id 필드)과 함께 사용할 수 있습니다. 예를 들면 다음과 같습니다.

{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key

샤드 키 필드가 변경할 수 없는 _id 필드가 아닌 경우 문서의 샤드 키 값을 업데이트할 수 있습니다.

경고

샤딩된 컬렉션의 문서에는 샤드 키 필드가 누락될 수 있습니다. 문서의 샤드 키 값을 변경할 때 실수로 샤드 키를 제거하지 않도록 주의해야 합니다.

기존 샤드 키 값을 db.collection.findAndModify()로 업데이트하려면 다음을 수행합니다.

  • 반드시 mongos에서 실행해야 합니다. 샤드에서 직접 작업을 실행하지 않아야 합니다.

  • 반드시 트랜잭션에서 실행하거나 재시도 가능 쓰기로 실행해야 합니다 .

  • 전체 샤드 키에 동등성 필터를 포함시켜야 합니다.

샤딩된 컬렉션의 문서에는 샤드 키 필드가 누락될 수 있습니다. db.collection.findAndModify()를 사용하여 문서의 누락된 샤드 키를 설정하려면 다음을 수행해야 합니다.

  • 반드시 mongos에서 실행해야 합니다. 샤드에서 직접 작업을 실행하지 않아야 합니다.

  • 새 샤드 키 값이 null이(가) 아닌 경우 트랜잭션 또는 재시도 가능 쓰기 중 하나로 실행해야 합니다.

  • 전체 샤드 키에 동등성 필터를 포함시켜야 합니다.

누락된 키 값은 null 동등성 매치의 일부로 반환되므로 null 값 키가 업데이트되지 않도록 하려면 추가 쿼리 조건(예: _id 필드)을 적절히 포함하세요.

다음도 참조하세요.

db.collection.findAndModify() 메서드는 유효성 검사 규칙이 있는 컬렉션에 문서를 삽입하거나 업데이트할 때 문서 유효성 검사를 건너뛸 수 있는 bypassDocumentValidation 옵션에 대한 지원을 추가합니다.

문서를 업데이트할 때 db.collection.findAndModify() 메서드와 updateOne() 메서드는 다음과 같이 서로 다르게 작동합니다.

  • 여러 문서가 업데이트 기준과 일치하는 경우 db.collection.findAndModify()sort를 지정하여 업데이트할 문서에 제어 수단을 제공할 수 있습니다.

    updateOne() 일치하는 첫 번째 문서를 업데이트합니다.

  • db.collection.findAndModify()는 기본적으로 이 문서의 수정 전 버전을 반환합니다. 업데이트된 문서를 받으려면 new 옵션을 사용하세요.

    updateOne() 메서드는 연산의 상태가 포함된 WriteResult() 객체를 반환합니다.

    업데이트된 문서를 반환하려면 find() 메서드를 사용하세요. 그러나 업데이트와 문서 검색 사이에 다른 업데이트로 인해 문서가 수정되었을 수 있습니다. 게다가 해당 업데이트로 인해 문서가 1개만 수정되었으나 여러 문서가 일치한 경우, 업데이트된 문서를 식별하기 위해서는 추가 로직을 사용해야 합니다.

단일 문서를 수정할 때는 db.collection.findAndModify() 메서드 및 updateOne() 메서드 둘 다 문서를 원자 단위로 업데이트합니다. 이 메서드들의 상호작용과 연산 순서에 대한 자세한 내용은 원자성 및 트랜잭션을 참조하세요.

db.collection.findAndModify()분산 트랜잭션 내에서 사용할 수 있습니다.

중요

대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.

추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.

트랜잭션이 교차 샤드 쓰기 트랜잭션(write transaction)이 아닌 경우 분산 트랜잭션 내에서 컬렉션과 인덱스를 생성할 수 있습니다.

upsert: truedb.collection.findAndModify()는 기존 컬렉션이나 존재하지 않는 컬렉션에서 실행될 수 있습니다. 존재하지 않는 컬렉션에서 실행하면 작업이 컬렉션을 만듭니다.

트랜잭션에서 실행되는 경우 작업에 대한 쓰기 고려를 명시적으로 설정하지 마세요. 트랜잭션에 쓰기 고려를 사용하려면 트랜잭션 및 쓰기 고려를 참조하세요.

db.collection.findAndModify() 작업이 문서를 성공적으로 찾아서 수정하면 작업은 oplog(작업 로그)에 항목을 추가합니다. 작업이 실패하거나 수정할 문서를 찾지 못하면 작업은 oplog에 항목을 추가하지 않습니다.

다음 메서드는 문서가 쿼리 기준과 일치하는 사람 컬렉션의 기존 문서를 업데이트하고 반환합니다.

db.people.findAndModify({
query: { name: "Tom", state: "active", rating: { $gt: 10 } },
sort: { rating: 1 },
update: { $inc: { score: 1 } }
})

이 메서드는 다음 작업을 실행합니다.

  1. query은(는) name 필드의 값이 Tom(이)고, state 필드의 값이 active(이)고, rating 필드의 값이 10 greater thanpeople 컬렉션에서 문서를 찾습니다.

  2. sort은(는) 쿼리 결과를 오름차순으로 정렬합니다. 여러 문서가 query 조건을 충족할 경우, 이 메서드는 이 sort(으)로 정렬된 첫 번째 문서를 수정하기로 선택합니다.

  3. increments은(는) score 필드의 값을 1씩 업데이트합니다.

  4. 이 메서드는 이 업데이트를 위해 선택된 원본(즉 수정 전) 문서를 반환합니다.

    {
    "_id" : ObjectId("50f1e2c99beb36a0f45c6453"),
    "name" : "Tom",
    "state" : "active",
    "rating" : 100,
    "score" : 5
    }

    업데이트된 문서를 반환하려면 메서드에 new:true 옵션을 추가합니다.

    query 조건과 일치하는 문서가 없을 경우 이 메서드는 null을(를) 반환합니다.

다음 메서드에는 일치하는 문서를 업데이트하거나, 일치하는 문서가 없는 경우 새 문서를 생성하는 update 연산의 upsert: true 옵션이 포함되어 있습니다.

db.people.findAndModify({
query: { name: "Gus", state: "active", rating: 100 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true
})

이 메서드가 일치하는 문서를 찾으면 업데이트가 실행됩니다.

이 메서드가 일치하는 문서를 찾지 못하면 새 문서가 생성됩니다. 이 메서드에 sort 옵션이 포함되어 있으므로 빈 문서 { }이(가) 원본(수정 전) 문서로 반환됩니다.

{ }

이 메서드에 sort 옵션이 포함되지 않은 경우에는 null이(가) 반환됩니다.

null

다음 메서드에는 upsert: true 옵션과 new:true 옵션이 모두 포함되어 있습니다. 이 메서드는 일치하는 문서를 업데이트하고 업데이트된 문서를 반환하거나, 일치하는 문서가 없는 경우 문서를 삽입하고 새로 삽입된 문서를 value 필드에 반환합니다.

다음 예시에서는 people 컬렉션의 어떤 문서도 query 조건과 일치하지 않습니다.

db.people.findAndModify({
query: { name: "Pascal", state: "active", rating: 25 },
sort: { rating: 1 },
update: { $inc: { score: 1 } },
upsert: true,
new: true
})

이 메서드는 새로 삽입된 문서를 다음과 같이 반환합니다.

{
"_id" : ObjectId("50f49ad6444c11ac2448a5d6"),
"name" : "Pascal",
"rating" : 25,
"score" : 1,
"state" : "active"
}

다음 예시에서는 rating 필드에 sort 사양을 포함시킴으로써, state 값이 active(이)면서 일치하는 문서 중 rating 값이 가장 낮은 단일 문서를 people 컬렉션에서 제거합니다.

db.people.findAndModify(
{
query: { state: "active" },
sort: { rating: 1 },
remove: true
}
)

이 메서드는 삭제된 문서를 다음과 같이 반환합니다.

{
"_id" : ObjectId("52fba867ab5fdca1299674ad"),
"name" : "XYZ123",
"score" : 1,
"state" : "active",
"rating" : 3
}

데이터 정렬을 사용하면 대소문자 및 악센트 표시 규칙과 같은 문자열 비교에 대한 언어별 규칙을 지정할 수 있습니다.

컬렉션 myColl에는 다음 문서가 있습니다.

{ _id: 1, category: "café", status: "A" }
{ _id: 2, category: "cafe", status: "a" }
{ _id: 3, category: "cafE", status: "a" }

다음 작업에는 데이터 정렬 옵션이 포함됩니다.

db.myColl.findAndModify({
query: { category: "cafe", status: "a" },
sort: { category: 1 },
update: { $set: { status: "Updated" } },
collation: { locale: "fr", strength: 1 }
});

연산은 다음 문서를 반환합니다.

{ "_id" : 1, "category" : "café", "status" : "A" }

참고

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>]을(를) db.collection.findAndModify() 메서드의 arrayFilters 옵션과 함께 사용하세요.

db.students.findAndModify({
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.students2.findAndModify({
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 }
]
}

db.collection.findAndModify() 업데이트를 위한 집계 파이프라인을 수락할 수 있습니다. 파이프라인은 다음 단계로 구성될 수 있습니다.

집계 파이프라인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.students2.findAndModify( {
query: { "_id" : 1 },
update: [ { $set: { "total" : { $sum: "$grades.grade" } } } ], // The $set stage is an alias for ``$addFields`` stage
new: true
} )

참고

이 파이프라인에 사용된 $set은(는) 업데이트 연산자 $set이(가) 아닌 집계 단계 $set을(를) 나타냅니다.

이 연산은 업데이트된 문서를 다음과 같이 반환합니다.

{
"_id" : 1,
"grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" : 85, "std" : 6 } ],
"total" : 250
}

버전 5.0에 추가.

명령의 다른 곳에서 액세스할 수 있는 변수를 정의하려면 let 옵션을 사용합니다.

참고

변수를 사용하여 결과를 필터링하려면 $expr 연산자 내에서 변수에 액세스해야 합니다.

컬렉션 cakeFlavors을 만듭니다:

db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )

다음 예시에서는 lettargetFlavor 변수를 정의하고, 이 변수를 사용하여 케이크 맛을 체리에서 오렌지로 변경합니다.

db.cakeFlavors.findAndModify( {
query: {
$expr: { $eq: [ "$flavor", "$$targetFlavor" ] }
},
update: { flavor: "orange" },
let: { targetFlavor: "cherry" }
} )

MongoDB 7.0부터는 새로운 USER_ROLES 시스템 변수를 사용하여 사용자 역할을 반환할 수 있습니다.

이 섹션의 예시에서는 의료 정보가 포함된 컬렉션의 필드에 대한 업데이트를 보여줍니다. 이 예시에서는 USER_ROLES 시스템 변수로부터 현재 사용자 역할을 읽고, 사용자에게 특정 역할이 있는 경우에만 업데이트를 실행합니다.

시스템 변수를 사용하려면 변수 이름 시작 부분에 $$를 추가합니다. USER_ROLES 시스템 변수를 $$USER_ROLES로 지정합니다.

이 예시에서는 다음과 같은 사용자를 생성합니다.

  • James Billing 역할이 있습니다.

  • Michelle Provider 역할이 있습니다.

역할, 사용자 및 컬렉션을 생성하려면 다음 단계를 수행하세요.

1

필수 권한 및 리소스로 이름이 Billing인 역할과 Provider인 역할을 생성하세요.

실행:

db.createRole( { role: "Billing", privileges: [ { resource: { db: "test",
collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
db.createRole( { role: "Provider", privileges: [ { resource: { db: "test",
collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
2

필수 역할로 이름이 James인 사용자와 Michelle인 사용자를 생성하세요.

db.createUser( {
user: "James",
pwd: "js008",
roles: [
{ role: "Billing", db: "test" }
]
} )
db.createUser( {
user: "Michelle",
pwd: "me009",
roles: [
{ role: "Provider", db: "test" }
]
} )
3

실행:

db.medical.insertMany( [
{
_id: 0,
patientName: "Jack Jones",
diagnosisCode: "CAS 17",
creditCard: "1234-5678-9012-3456"
},
{
_id: 1,
patientName: "Mary Smith",
diagnosisCode: "ACH 01",
creditCard: "6541-7534-9637-3456"
}
] )

Provider 역할이 있는 Michelle(으)로 로그인하여 다음과 같이 업데이트를 실행하세요.

1

실행:

db.auth( "Michelle", "me009" )
2

실행:

// Attempt to find and modify document
db.medical.findAndModify( {
query:
{ $and: [
{
// Only update the document for Mary Smith
patientName: { $eq: "Mary Smith" }
},
{
// User must have the Provider role to perform the update
$expr: { $ne: [ {
$setIntersection: [ [ "Provider" ], "$$USER_ROLES.role" ]
}, [] ] }
}
]
},
// Update document
update: {
patientName: "Mary Smith",
diagnosisCode: "ACH 03",
creditCard: "6541-7534-9637-3456"
}
} )

이전 예시에서는 $setIntersection을(를) 사용하여 "Provider" 문자열과 $$USER_ROLES.role 소속 사용자 역할 사이의 교차점이 비어 있지 않은 문서를 반환합니다. Michelle에게 Provider 역할이 있으므로 업데이트가 실행되었습니다.

이어서 Provider 역할이 없는 James(으)로 로그인하고 동일한 업데이트를 실행해 보세요.

1

실행:

db.auth( "James", "js008" )
2

실행:

// Attempt to find and modify document
db.medical.findAndModify( {
query:
{ $and: [
{
// Only update the document for Mary Smith
patientName: { $eq: "Mary Smith" }
},
{
// User must have the Provider role to perform the update
$expr: { $ne: [ {
$setIntersection: [ [ "Provider" ], "$$USER_ROLES.role" ]
}, [] ] }
}
]
},
// Update document
update: {
patientName: "Mary Smith",
diagnosisCode: "ACH 03",
creditCard: "6541-7534-9637-3456"
}
} )

이전 예시에서는 어떤 문서도 업데이트하지 않습니다.

돌아가기

db.collection.find