뷰 만들기 및 쿼리
이 페이지의 내용
뷰를 만들려면 다음 방법 중 하나를 사용합니다.
다음을 사용하세요.
db.createCollection()
다음을 사용하세요.
db.createView()
MongoDB Atlas UI에서 뷰를 만들려면 구체화된 뷰를 사용해야 합니다. 자세히 알아보려면 MongoDB Atlas UI에서 구체화된 뷰 만들기를 참조하세요.
중요
컬렉션 목록 출력에 뷰 이름이 포함됨
db.getCollectionInfos()
및 db.getCollectionNames()
같이 컬렉션을 나열하는 연산은 출력에 뷰를 포함합니다.
뷰 정의는 공개입니다. 즉, 뷰에 대한 db.getCollectionInfos()
및 explain
작업에는 뷰를 정의하는 파이프라인이 포함됩니다. 따라서 뷰 정의에 민감한 필드와 값을 직접 참조하지 않는 것이 좋습니다.
db.createCollection()
구문
db.createCollection( "<viewName>", { "viewOn" : "<source>", "pipeline" : [<pipeline>], "collation" : { <collation> } } )
db.createView()
구문
db.createView( "<viewName>", "<source>", [<pipeline>], { "collation" : { <collation> } } )
제한 사항
원본 컬렉션과 동일한 데이터베이스에 뷰를 만들어야 합니다.
보기 정의
pipeline
에는$out
또는$merge
단계를 포함할 수 없습니다. 이 제한은$lookup
단계 또는$facet
단계에서 사용되는 파이프라인과 같은 임베디드 파이프라인에도 적용됩니다.뷰를 만든 후에는 이름을 변경할 수 없습니다.
지원되지 않는 작업
일부 작업은 뷰에서 사용할 수 없습니다.
집계에서
$text
는 첫 번째 단계에만 유효하므로$text
연산자를 사용할 수 없습니다.뷰 이름 변경.
자세한 내용은 뷰에 대해 지원되는 작업을 참조하세요.
예시
첫 번째 예에서는 학생 데이터로 컬렉션을 채우고 데이터를 쿼리하는 뷰를 만듭니다.
컬렉션 채우기
이 예시에 사용할 students
컬렉션을 만듭니다.
db.students.insertMany( [ { sID: 22001, name: "Alex", year: 1, score: 4.0 }, { sID: 21001, name: "bernie", year: 2, score: 3.7 }, { sID: 20010, name: "Chris", year: 3, score: 2.5 }, { sID: 22021, name: "Drew", year: 1, score: 3.2 }, { sID: 17301, name: "harley", year: 6, score: 3.1 }, { sID: 21022, name: "Farmer", year: 1, score: 2.2 }, { sID: 20020, name: "george", year: 3, score: 2.8 }, { sID: 18020, name: "Harley", year: 5, score: 2.8 }, ] )
db.createView()를 사용하여 뷰 만들기
db.createView()
를 사용하여 1학년 학생으로 제한되는 뷰를 만듭니다.
db.createView( "firstYears", "students", [ { $match: { year: 1 } } ] )
예시:
firstYears
새 뷰의 이름입니다.students
뷰의 기반이 되는 컬렉션입니다.$match
는students
컬렉션의 1학년 학생과 일치하는 집계 표현식입니다.
뷰 쿼리
이 예에서는 뷰를 쿼리합니다.
db.firstYears.find({}, { _id: 0 } )
다음 출력에는 1학년 학생에 대한 데이터가 있는 문서만 포함되어 있습니다. { _id: 0 }
프로젝션은 출력 디스플레이에 _id
필드를 표시하지 않습니다.
[ { sID: 22001, name: 'Alex', year: 1, score: 4 }, { sID: 22021, name: 'Drew', year: 1, score: 3.2 }, { sID: 21022, name: 'Farmer', year: 1, score: 2.2 } ]
db.createCollection()을 사용하여 뷰 만들기
db.createCollection()
메서드를 사용하면 특정 옵션이 있는 컬렉션 또는 뷰를 만들 수 있습니다.
다음 예에서는 graduateStudents
뷰를 만듭니다. 뷰에는 $match
단계에서 선택한 문서만 포함되어 있습니다. 선택적 데이터 정렬 설정에 따라 정렬 순서가 결정됩니다.
db.createCollection( "graduateStudents", { viewOn: "students", pipeline: [ { $match: { $expr: { $gt: [ "$year", 4 ] } } } ], collation: { locale: "en", caseFirst: "upper" } } )
참고
데이터 정렬 동작
뷰를 만들 때 뷰의 기본 데이터 정렬을 지정할 수 있습니다. 데이터 정렬이 지정되지 않은 경우, 뷰의 기본 데이터 정렬은 "simple" 이진 비교 데이터 정렬기입니다. 즉, 뷰는 컬렉션의 기본 데이터 정렬을 상속하지 않습니다.
뷰의 문자열 비교에서는 뷰의 기본 데이터 정렬을 사용합니다. 뷰의 기본 데이터 정렬을 변경하거나 재정의하려는 작업은 오류를 반환하며 실패합니다.
다른 보기에서 보기를 만드는 경우 원본 보기의 데이터 정렬과 다른 데이터 정렬을 지정할 수 없습니다.
$lookup
또는$graphLookup
과 같이 여러 뷰를 포함하는 집계를 수행하는 경우 뷰의 데이터 정렬이 동일해야 합니다.
뷰 쿼리
다음 예시에서는 보기를 쿼리합니다. $unset
단계에서는 명확성을 위해 출력에서 _id
필드를 제거합니다.
db.graduateStudents.aggregate( [ { $sort: { name: 1 } }, { $unset: [ "_id" ] } ] )
출력이 정렬될 때 $sort
단계에서는 데이터 정렬 순서를 사용하여 대문자를 소문자보다 먼저 정렬합니다.
[ { sID: 18020, name: 'Harley', year: 5, score: 2.8 }, { sID: 17301, name: 'harley', year: 6, score: 3.1 } ]
현재 사용자에게 부여된 역할에 대한 의료 정보 조회
MongoDB 7.0부터는 새로운 USER_ROLES
시스템 변수를 사용하여 사용자 역할을 반환할 수 있습니다.
이 섹션의 예에서는 의료 정보가 포함된 컬렉션의 필드에 대한 접근 권한이 제한된 사용자를 보여줍니다. 이 예시에서는 USER_ROLES
시스템 변수에서 현재 사용자 역할을 읽고 역할에 따라 필드를 숨기는 뷰를 사용합니다.
이 예시에서는 다음과 같은 사용자를 생성합니다.
James
creditCard
필드에 액세스할 수 있는Billing
역할로 바꿉니다.Michelle
diagnosisCode
필드에 액세스할 수 있는Provider
역할로 바꿉니다.
다음 단계를 수행하여 역할, 사용자, 컬렉션 및 뷰를 만듭니다.
뷰 만들기
시스템 변수를 사용하려면 변수 이름 시작 부분에 $$
를 추가합니다. USER_ROLES
시스템 변수를 $$USER_ROLES
로 지정합니다.
보기는 USER_ROLES
시스템 변수에서 현재 사용자 역할을 읽고 역할에 따라 필드를 숨깁니다.
실행:
db.createView( "medicalView", "medical", [ { $set: { "diagnosisCode": { $cond: { if: { $in: [ "Provider", "$$USER_ROLES.role" ] }, then: "$diagnosisCode", else: "$$REMOVE" } } }, }, { $set: { "creditCard": { $cond: { if: { $in: [ "Billing", "$$USER_ROLES.role" ] }, then: "$creditCard", else: "$$REMOVE" } } } } ] )
뷰 예시
James
에 액세스할 수 있는 정보를 검색하려면 다음 단계를 수행하십시오.
Michelle
에 액세스할 수 있는 정보를 검색하려면 다음 단계를 수행하십시오.
현재 사용자에게 부여된 역할에 대한 예산 문서 조회
MongoDB 7.0부터는 새로운 USER_ROLES
시스템 변수를 사용하여 사용자 역할을 반환할 수 있습니다.
이 섹션의 시나리오에서는 예산 정보가 포함된 컬렉션의 문서에 대한 액세스 권한이 제한된 다양한 역할의 사용자를 보여줍니다.
이 시나리오는 USER_ROLES
의 한 가지 가능한 용도를 보여 줍니다. budget
collection에는 allowedRoles
(이)라는 필드가 있는 문서가 포함되어 있습니다. 다음 시나리오에서 볼 수 있듯이 allowedRoles
필드에 있는 사용자 역할을 USER_ROLES
시스템 변수에서 반환한 역할과 비교하는 쿼리를 쓸 수 있습니다.
참고
다른 USER_ROLES
예시 시나리오는현재 사용자에게 부여된 역할에 대한 의료 정보 조회를 참조하세요. 이 예에서는 다음 예에서처럼 문서 필드에 사용자 역할을 저장하지 않습니다.
이 섹션의 예산 시나리오의 경우 다음 단계를 수행하여 역할, 사용자 및 budget
컬렉션을 만들 수 있습니다.
사용자 만들기
필수 역할로 John
및 Jane
이라는 이름의 사용자를 만듭니다. test
데이터베이스를 데이터베이스 이름으로 바꿉니다.
db.createUser( { user: "John", pwd: "jn008", roles: [ { role: "Marketing", db: "test" }, { role: "Development", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } ) db.createUser( { user: "Jane", pwd: "je009", roles: [ { role: "Sales", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } )
컬렉션 생성
실행:
db.budget.insertMany( [ { _id: 0, allowedRoles: [ "Marketing" ], comment: "For marketing team", yearlyBudget: 15000 }, { _id: 1, allowedRoles: [ "Sales" ], comment: "For sales team", yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ "Operations" ], comment: "For operations team", yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ "Development" ], comment: "For development team", yearlyBudget: 27000 } ] )
뷰를 생성하고 John
에 액세스할 수 있는 문서를 검색하려면 다음 단계를 수행하세요.
뷰 만들기
시스템 변수를 사용하려면 변수 이름 시작 부분에 $$
를 추가합니다. USER_ROLES
시스템 변수를 $$USER_ROLES
로 지정합니다.
실행:
db.createView( "budgetView", "budget", [ { $match: { $expr: { $not: { $eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ] } } } } ] )
뷰를 생성할 수 없는 경우 뷰를 생성할 수 있는 권한이 있는 사용자로 로그인했는지 확인합니다.
이전 예시에서는 예시를 실행하는 사용자가 가진 역할 중 하나 이상과 일치하는 budget
컬렉션의 문서를 반환합니다. 이를 위해 이 예시에서는 $setIntersection
을 사용하여 budget
문서 allowedRoles
필드와 $$USER_ROLES
의 사용자 역할 세트 사이의 교집합이 비어 있지 않은 문서를 반환합니다.
문서 검토
John
Marketing
, Operations
및 Development
역할이 있으며 다음과 같은 문서를 볼 수 있습니다.
[ { _id: 0, allowedRoles: [ 'Marketing' ], comment: 'For marketing team', yearlyBudget: 15000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ 'Development' ], comment: 'For development team', yearlyBudget: 27000 } ]
Jane이 액세스할 수 있는 문서를 검색하려면 다음 단계를 수행하세요.
문서 검토
Jane
은(는) Sales
및 Operations
역할을 가지며 다음과 같은 문서를 볼 수 있습니다.
[ { _id: 1, allowedRoles: [ 'Sales' ], comment: 'For sales team', yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 } ]
참고
샤딩된 클러스터에서는 사용자를 대신하여 다른 서버 노드가 샤드에서 쿼리를 실행할 수 있습니다. 이러한 쿼리에서 USER_ROLES
는 여전히 사용자에 대한 역할로 채워져 있습니다.
여러 데이터베이스에서 동일한 이름을 가진 역할
동일한 이름의 역할이 여러 데이터베이스에 있을 수 있습니다. 뷰를 만들고 뷰에서 특정 역할을 참고하는 경우 db
데이터베이스 이름 필드와 role
필드를 모두 지정하거나 데이터베이스 이름과 역할이 포함된 _id
필드를 지정해야 합니다.
다음 예에서는 다른 이름의 역할이 있는 Jane
에 할당된 역할을 반환합니다. 이 예에서는 _id
, role
및 db
데이터베이스 이름을 반환합니다:
행동
다음 섹션에서는 뷰 만들기 및 쿼리의 동작에 대해 설명합니다.
집계 최적화
뷰를 쿼리하는 경우:
db.collection.find()
에 대한 쿼리filter
,projection
,sort
,skip
,limit
및 기타 작업은 해당 집계 파이프라인 단계로변환됩니다.MongoDB는 클라이언트 쿼리를 기본 파이프라인에 추가하고 결합된 파이프라인의 결과를 클라이언트에 반환합니다. MongoDB는 결합된 파이프라인에 집계 파이프라인 최적화 를 적용할 수 있습니다.
집계 파이프라인 옵티마이저는 성능을 향상시키기 위해 뷰 집계 파이프라인 스테이지를 재구성합니다. 최적화로 인해 쿼리 결과가 변경되지는 않습니다.
리소스 잠금
db.createView()
은(는) 작업 기간 동안 지정된 컬렉션 또는 뷰에 대한 배타 락을 얻습니다. 컬렉션에 대한 모든 후속 작업은 db.createView()
이(가) 잠금을 해제할 때까지 기다려야 합니다. db.createView()
은(는) 일반적으로 짧은 시간 동안 이 잠금을 유지합니다.
뷰를 만들려면 데이터베이스의 system.views
컬렉션에 대한 추가 배타 락을 얻어야 합니다. 이 잠금은 명령이 완료될 때까지 데이터베이스의 뷰 생성 또는 수정을 차단합니다.