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

$project (집계)

이 페이지의 내용

  • 정의
  • 호환성
  • 구문
  • 행동
  • 고려 사항
  • 예시
$project

요청된 필드가 있는 문서를 파이프라인의 다음 단계로 전달합니다. 지정된 필드는 입력 문서의 기존 필드일 수도 있고 새로 계산된 필드일 수도 있습니다.

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

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

  • MongoDB Enterprise: MongoDB의 구독 기반 자체 관리 버전

  • MongoDB Community: MongoDB의 소스 사용 가능 무료 자체 관리 버전

$project 단계의 프로토타입 형식은 다음과 같습니다.

{ $project: { <specification(s)> } }

$project는 필드 포함, _id 필드 표시 안 함, 새 필드 추가, 기존 필드 값 재설정을 지정할 수 있는 문서를 사용합니다. 또는 필드 제외를 지정할 수 있습니다.

$project 사양의 형식은 다음과 같습니다.

형식
설명
<field>: <1 or true>
필드 포함 여부를 지정합니다. 0이 아닌 정수도 true로 처리됩니다.
_id: <0 or false>

_id 필드의 억제를 지정합니다.

조건부로 필드를 제외하려면 REMOVE 변수를 대신 사용합니다. 자세한 내용은 조건부로 필드 제외를 참조하세요.

<field>: <expression>

새 필드를 추가하거나 기존 필드의 값을 재설정합니다.

표현식이 $$REMOVE로 평가되면 해당 필드가 출력에서 제외됩니다. 자세한 내용은 조건부로 필드 제외를 참조하세요.

<field>: <0 or false>

필드 제외 여부를 지정합니다.

조건부로 필드를 제외하려면 REMOVE 변수를 대신 사용합니다. 자세한 내용은 조건부로 필드 제외를 참조하세요.

_id 이외의 필드를 제외하도록 지정하면 다른 $project 사양 양식을 사용할 수 없습니다. 이 제한은 REMOVE 변수를 사용하여 필드를 조건부로 제외하는 경우에는 적용되지 않습니다.

필드를 제외하려면 $unset 단계도 참조하세요.

  • _id 필드는 기본적으로 출력 문서에 포함됩니다. 입력 문서의 다른 필드를 출력 문서에 포함하려면 $project에 포함을 명시적으로 지정해야 합니다.

  • 문서에 존재하지 않는 필드의 포함을 지정하면 $project(은)는 해당 필드 포함을 무시하고 해당 필드를 문서에 추가하지 않습니다.

_id 필드는 출력 문서에 포함되도록 기본 설정되어 있습니다. 출력 문서에서 _id 필드를 제외하려면 $project에서 _id 필드를 사용하지 않음을 명시적으로 지정해야 합니다.

필드 제외를 지정하면 다른 모든 필드가 출력 문서에 반환됩니다.

{ $project: { "<field1>": 0, "<field2>": 0, ... } } // Return all but the specified fields

_id 이외의 필드를 제외하도록 지정하면 다른 $project 지정 양식을 사용할 수 없습니다. 즉, 필드를 제외하면 필드 포함을 지정하거나 기존 필드 값을 재설정하거나 새 필드를 추가할 수도 없습니다. 이 제한은 REMOVE 변수를 사용하여 필드를 조건부로 제외하는 경우에는 적용되지 않습니다.

필드를 제외하려면 $unset 단계도 참조하세요.

집계 표현식에서 변수 REMOVE(을)를 사용하여 조건부로 필드를 억제할 수 있습니다. 예시를 보려면 조건부로 필드 제외를 참조하세요.

참고

MongoDB는 문서에 새 필드를 추가할 수 있는 $addFields도 제공합니다.

새 필드를 추가하거나 기존 필드의 값을 재설정하려면 필드 이름을 지정하고 해당 값을 특정 표현식으로 설정합니다. 표현식에 대한 자세한 내용은 표현식 연산자를 참조하세요.

필드를 리터럴로 리졸브되는 표현식으로 설정하는 대신 필드 값을 숫자 또는 부울 리터럴로 직접 설정하려면 $literal 연산자를 사용합니다. 그렇지 않으면 $project가 숫자 또는 부울 리터럴을 필드를 포함하거나 제외할 때 플래그로 처리합니다.

새 필드를 지정하고 해당 값을 기존 필드의 필드 경로로 설정하면 필드 이름을 효과적으로 변경할 수 있습니다.

$project 단계는 대괄호 [](을)를 사용해 새 배열 필드를 직접 만들 수 있도록 지원합니다. 문서에 존재하지 않는 배열 필드를 지정하는 경우, 연산은 해당 필드의 값으로 null(을)를 대체합니다. 예시는 새 배열 필드 프로젝트를 참조하세요.

배열 인덱스는 $project 단계와 함께 사용할 수 없습니다. 자세한 내용은 배열 인덱스가 지원되지 않음을 참조하세요.

내장된 문서 내에서 필드를 프로젝션하거나 추가/재설정할 때 다음과 같이 점 표기법을 사용할 수 있습니다.

"contact.address.country": <1 or 0 or expression>

또는 필드를 중첩할 수도 있습니다:

contact: { address: { country: <1 or 0 or expression> } }

필드를 중첩할 때 내장된 문서 내에서 점 표기법을 사용하여 필드를 지정할 수 없습니다(예: contact: { "address.country": <1 or 0 or expression> }은(는) 유효하지 않습니다).

내장된 문서와 이 내장된 문서 내의 필드를 동일한 프로젝션에 모두 지정할 수는 없습니다.

다음 $project 단계는 내장된 contact 문서와 contact.address.country 필드를 모두 프로젝션하려고 시도하기 때문에 실패하며 Path collision 오류를 반환합니다.

{ $project: { contact: 1, "contact.address.country": 1 } }

이 오류는 상위 문서와 임베디드 필드가 지정된 순서와 관계없이 발생합니다. 다음 $project도 동일한 오류로 인해 실패합니다.

{ $project: { "contact.address.country": 1, contact: 1 } }

$project 단계를 사용하는 경우 이 단계는 일반적으로 파이프라인의 마지막 단계로, 클라이언트에 반환할 필드를 지정하는 데 사용됩니다.

파이프라인의 시작 또는 중간에 $project 단계를 사용하여 후속 파이프라인 단계로 전달되는 필드 수를 줄이면 데이터베이스에서 이 최적화를 자동으로 수행하므로 성능이 향상되지 않을 수 있습니다.

MongoDB는 $project 단계에 빈 문서가 전달되면 오류를 반환합니다.

예를 들어 다음 파이프라인을 실행하면 오류가 발생합니다.

db.myCollection.aggregate( [ {
$project: { }
} ] )

배열 인덱스는 $project 단계와 함께 사용할 수 없습니다. 자세한 내용은 배열 인덱스가 지원되지 않음을 참조하세요.

다음 문서가 포함된 collection을 고려합니다:books

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}

다음 $project 단계는 출력 문서에 _id, title, author 필드만 포함합니다.

db.books.aggregate( [ { $project : { title : 1 , author : 1 } } ] )

이 연산을 수행하면 다음 문서가 생성됩니다.

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

_id 필드는 기본적으로 항상 포함됩니다. $project 단계의 출력 문서에서 _id 필드를 제외하려면 프로젝션 문서에서 _id 필드를 0으로 설정하여 제외를 지정합니다.

다음 문서가 포함된 collection을 고려합니다:books

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}

다음 $project 단계에서는 출력 문서에 _id 필드를 제외하지만 titleauthor 필드를 포함합니다.

db.books.aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )

이 연산을 수행하면 다음 문서가 생성됩니다.

{ "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

다음 문서가 포함된 collection을 고려합니다:books

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}

다음 $project 단계에서는 출력에서 lastModified 필드를 제외합니다.

db.books.aggregate( [ { $project : { "lastModified": 0 } } ] )

필드를 제외하려면 $unset 단계도 참조하세요.

다음 문서가 포함된 collection을 고려합니다:books

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}

다음 $project 단계에서는 출력에서 author.firstlastModified 필드를 제외합니다.

db.books.aggregate( [ { $project : { "author.first" : 0, "lastModified" : 0 } } ] )

또는 문서에 제외 사양을 중첩할 수도 있습니다.

db.bookmarks.aggregate( [ { $project: { "author": { "first": 0}, "lastModified" : 0 } } ] )

두 사양 모두 동일한 출력이 생성됩니다.

{
"_id" : 1,
"title" : "abc123",
"isbn" : "0001122223334",
"author" : {
"last" : "zzz"
},
"copies" : 5,
}

필드를 제외하려면 $unset 단계도 참조하세요.

집계 표현식에서 변수 REMOVE를 사용하여 조건부로 필드를 억제할 수 있습니다.

다음 문서가 포함된 collection을 고려합니다:books

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5,
lastModified: "2016-07-28"
}
{
"_id" : 2,
title: "Baked Goods",
isbn: "9999999999999",
author: { last: "xyz", first: "abc", middle: "" },
copies: 2,
lastModified: "2017-07-21"
}
{
"_id" : 3,
title: "Ice Cream Cakes",
isbn: "8888888888888",
author: { last: "xyz", first: "abc", middle: "mmm" },
copies: 5,
lastModified: "2017-07-22"
}

다음 $project 단계에서는 REMOVE 변수를 사용해 author.middle 필드가 ""와 동일한 경우에만 제외합니다.

db.books.aggregate( [
{
$project: {
title: 1,
"author.first": 1,
"author.last" : 1,
"author.middle": {
$cond: {
if: { $eq: [ "", "$author.middle" ] },
then: "$$REMOVE",
else: "$author.middle"
}
}
}
}
] )

집계 연산을 수행하면 다음과 같은 결과가 출력됩니다.

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
{ "_id" : 2, "title" : "Baked Goods", "author" : { "last" : "xyz", "first" : "abc" } }
{ "_id" : 3, "title" : "Ice Cream Cakes", "author" : { "last" : "xyz", "first" : "abc", "middle" : "mmm" } }

addFields와 비교

$addFields 또는 $project 단계를 사용하여 문서 필드를 제거할 수 있습니다. 가장 좋은 방법은 파이프라인 과 보존하려는 원본 문서 의 양에 따라 달라집니다.

$addFields 단계에서 $$REMOVE 사용하는 예를 보려면 필드 제거를 참조하세요.

다음 문서가 포함된 bookmarks collection을 생각해 보세요.

{ _id: 1, user: "1234", stop: { title: "book1", author: "xyz", page: 32 } }
{ _id: 2, user: "7890", stop: [ { title: "book2", author: "abc", page: 5 }, { title: "book3", author: "ijk", page: 100 } ] }

stop 필드의 내장된 문서에 title 필드만 포함하려면 점 표기법을 사용하면 됩니다.

db.bookmarks.aggregate( [ { $project: { "stop.title": 1 } } ] )

또는 문서에 포함 사양을 중첩할 수 있습니다.

db.bookmarks.aggregate( [ { $project: { stop: { title: 1 } } } ] )

두 사양 모두 다음과 같은 문서가 생성됩니다.

{ "_id" : 1, "stop" : { "title" : "book1" } }
{ "_id" : 2, "stop" : [ { "title" : "book2" }, { "title" : "book3" } ] }

다음 문서가 포함된 collection을 고려합니다:books

{
"_id" : 1,
title: "abc123",
isbn: "0001122223334",
author: { last: "zzz", first: "aaa" },
copies: 5
}

다음 $project 단계에서는 새 필드 isbn, lastNamecopiesSold를 추가합니다.

db.books.aggregate(
[
{
$project: {
title: 1,
isbn: {
prefix: { $substr: [ "$isbn", 0, 3 ] },
group: { $substr: [ "$isbn", 3, 2 ] },
publisher: { $substr: [ "$isbn", 5, 4 ] },
title: { $substr: [ "$isbn", 9, 3 ] },
checkDigit: { $substr: [ "$isbn", 12, 1] }
},
lastName: "$author.last",
copiesSold: "$copies"
}
}
]
)

이 연산을 수행하면 다음 문서가 생성됩니다.

{
"_id" : 1,
"title" : "abc123",
"isbn" : {
"prefix" : "000",
"group" : "11",
"publisher" : "2222",
"title" : "333",
"checkDigit" : "4"
},
"lastName" : "zzz",
"copiesSold" : 5
}

예를 들어 컬렉션에 다음 문서가 포함되어 있다고 가정해 보겠습니다.

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "x" : 1, "y" : 1 }

다음 작업은 xy 필드를 새 필드 myArray의 요소로 프로젝트합니다.

db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y" ] } } ] )

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

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1 ] }

배열 사양이 문서에 존재하지 않는 필드를 포함하는 경우 연산은 null을 해당 필드의 값으로 대체합니다.

예를 들어 위와 동일한 문서가 주어졌을 때 다음 연산은 x, y 필드와 존재하지 않는 필드 $someField를 새 필드 myArray의 요소로 투영합니다.

db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y", "$someField" ] } } ] )

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

{ "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1, null ] }

배열 인덱스는 $project 단계와 함께 사용할 수 없습니다. 이 섹션에서 예시를 함께 살펴봅시다.

다음 pizzas 컬렉션을 만듭니다:

db.pizzas.insert( [
{ _id: 0, name: [ 'Pepperoni' ] },
] )

다음 예시는 피자를 반환합니다.

db.pizzas.aggregate( [
{ $project: { x: '$name', _id: 0 } },
] )

예시 출력에서는 피자가 반환됩니다.

[ { x: [ 'Pepperoni' ] } ]

다음 예시는 배열 인덱스($name.0)를 사용해 피자를 반환하려고 시도합니다.

db.pizzas.aggregate( [
{ $project: { x: '$name.0', _id: 0 } },
] )

예시 출력에서는 피자가 반환되지 않습니다:

[ { x: [] } ]

돌아가기

$planCacheStats