$ (projection)
정의
사용 고려 사항
$
연산자와 $elemMatch
연산자는 모두 조건에 따라 배열에서 일치하는 첫 번째 요소를 프로젝션합니다.
$
연산자는 쿼리 문의 일부 조건에 따라 컬렉션의 각 문서에서 가장 먼저 일치하는 배열 요소를 투영합니다.
$elemMatch
프로젝션 연산자는 명시적 조건 인수를 받습니다. 이를 통해 쿼리에 없는 조건을 기반으로 프로젝트하거나, 배열에 내장된 문서의 여러 필드를 기반으로 프로젝트할 수 있습니다. 예시는 배열 필드 제한을 참조하세요.
db.collection.find()
뷰 에 대한 작업은 $
투영 연산자를 지원하지 않습니다.
행동
구문
배열에 지정된 쿼리 조건과 일치하는 첫 번째 배열 요소를 반환하려면 다음을 수행하세요.
db.collection.find( { <array>: <condition> ... }, { "<array>.$": 1 } ) db.collection.find( { <array.field>: <condition> ...}, { "<array>.$": 1 } )
$
연산자를 사용하여 쿼리 문서에 표시되지 않는 <array>
필드를 제한할 수 있습니다. 이전 버전의 MongoDB에서는 제한되는 <array>
필드가 쿼리 문서에 반드시 나타나야 합니다.
db.collection.find( { <someOtherArray>: <condition> ... }, { "<array>.$" : 1 } )
중요
예상되는 동작을 보장하려면 쿼리 문서와 프로젝션 문서에 사용되는 배열의 길이가 동일해야 합니다. 배열의 길이가 다른 경우 특정 시나리오에서 작업이 오류를 일으킬 수 있습니다.
배열 필드 제한
MongoDB에서는 배열에 대한 프로젝션을 처리할 때 다음이 필요합니다.
프로젝션 문서에는 하나의 위치
$
연산자만 나타날 수 있습니다.쿼리 문서에는 하나의 배열 필드만 표시되어야 합니다. 쿼리 문서에 배열 필드를 추가하면 정의되지 않은 동작이 발생할 수 있습니다.
예를 들어 다음 프로젝션으로 인해 정의되지 않은 동작이 발생할 수 있습니다.
db.collection.find( { <array>: <value>, <someOtherArray>: <value2> }, { "<array>.$": 1 } ) 쿼리 문서에는 조건이 적용되는 배열 필드에 대한 단일 조건만 포함되어야 합니다. 여러 조건이 서로 상충하여 정의되지 않은 동작을 유발할 수 있습니다.
해당 배열 내의 문서의 여러 필드에 대한 기준을 지정하려면
$elemMatch
쿼리 연산자를 사용합니다. 예를 들어 다음 쿼리는mean
이 70보다 크고grade
가 90보다 큰grades
배열 내의 첫 번째 문서를 반환합니다.db.students.find( { grades: { $elemMatch: { mean: { $gt: 70 }, grade: { $gt:90 } } } }, { "grades.$": 1 } ) 문서를 선택하는 조건과 해당 문서 내의 필드를 선택하는 조건을 분리해야 하는 경우에도
$elemMatch
연산자를 사용해야 합니다.
정렬 및 위치 연산자
find()
메서드에 sort()
가 포함된 경우 find()
메서드는 위치 $
프로젝션 연산자를 적용하기 전에 일치하는 문서를 정렬하는sort()
를 적용합니다.
배열 필드에 필드 이름이 같은 문서가 여러 개 포함되어 있고 find()
메서드에 해당 반복 필드에 대한 sort()
가 포함되어 있는 경우, $
프로젝션 연산자 이전에 정렬이 배열 요소에 적용되었으므로 반환된 문서에 정렬 순서가 반영되지 않을 수 있습니다.
위치 연산자 배치 제한
$
프로젝션 연산자는 필드 경로의 끝(예시: "field.$"
또는 "fieldA.fieldB.$"
)에만 나타날 수 있습니다.
예를 들어 다음 연산은 유효하지 않습니다.
db.inventory.find( { }, { "instock.$.qty": 1 } )
해결하려면 $
프로젝션 연산자 뒤에 오는 필드 경로의 구성 요소를 제거합니다.
위치 $slice
연산자 및 제한
find
및 findAndModify
프로젝션은 $
프로젝션 표현식의 일부로 $slice
프로젝션 표현식을 포함할 수 없습니다.
예를 들어 다음 연산은 유효하지 않습니다.
db.inventory.find( { "instock.qty": { $gt: 25 } }, { "instock.$": { $slice: 1 } } )
이전 버전에서 MongoDB는 쿼리 조건과 일치하는 instock
배열의 첫 번째 요소 (instock.$
)를 반환합니다. 즉, 위치 프로젝션 "instock.$"
이(가) 우선하고 $slice:1
은(는) 작동하지 않습니다. "instock.$": {
$slice: 1 }
은(는) 다른 문서 필드를 제외하지 않습니다.
예시
프로젝트 배열 값
students
컬렉션에 포함된 문서는 다음과 같습니다.
{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] } { "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] } { "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] } { "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] } { "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] } { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }
다음 쿼리에서 프로젝션 { "grades.$": 1 }
는 grades
필드에 대해 85
이상인 첫 번째 요소만 반환합니다.
db.students.find( { semester: 1, grades: { $gte: 85 } }, { "grades.$": 1 } )
이 작업은 다음 문서를 반환합니다.
{ "_id" : 1, "grades" : [ 87 ] } { "_id" : 2, "grades" : [ 90 ] } { "_id" : 3, "grades" : [ 85 ] }
배열 필드 grades
에 85
보다 크거나 같은 요소가 여러 개 포함될 수 있지만, $
프로젝션 연산자는 배열에서 첫 번째로 일치하는 요소만 반환합니다.
프로젝트 배열 문서
students
collection에는 grades
필드가 문서의 배열인 다음 문서가 포함되며, 각 문서에는 grade
, mean
, std
라는 세 개의 필드 이름이 있습니다.
{ "_id" : 7, semester: 3, "grades" : [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 5 }, { grade: 90, mean: 85, std: 3 } ] } { "_id" : 8, semester: 3, "grades" : [ { grade: 92, mean: 88, std: 8 }, { grade: 78, mean: 90, std: 5 }, { grade: 88, mean: 85, std: 3 } ] }
다음 쿼리에서 { "grades.$": 1 }
프로젝션은 grades
필드에 대해 mean
가 70
보다 큰 첫 번째 요소만 반환합니다.
db.students.find( { "grades.mean": { $gt: 70 } }, { "grades.$": 1 } )
이 작업은 다음 문서를 반환합니다.
{ "_id" : 7, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 } ] } { "_id" : 8, "grades" : [ { "grade" : 92, "mean" : 88, "std" : 8 } ] }