온디맨드 구체화된 보기
온디맨드 구체화된 뷰는 디스크에 저장되고 디스크에서 읽히는 미리 계산된 집계 파이프라인 결과입니다. 온디맨드 구체화된 뷰는 일반적으로 $merge
또는 $out
단계의 결과물입니다.
표준 뷰와 비교
MongoDB는 표준 뷰와 온디맨드 구체화된 뷰의 두 가지 뷰 유형을 제공합니다. 두 뷰 유형 모두 집계 파이프라인에서 결과를 반환합니다.
표준 뷰는 뷰를 읽을 때 계산되며 디스크에 저장되지 않습니다.
온디맨드 구체화된 뷰는 디스크에 저장되고 디스크에서 읽혀집니다.
$merge
또는$out
단계를 사용하여 저장된 데이터를 업데이트합니다.
Indexes
표준 뷰는 기본 컬렉션의 인덱스를 사용합니다. 따라서 표준 뷰에서 직접 인덱스를 생성, 제거 또는 다시 작성할 수 없으며 뷰에서 인덱스 목록을 가져올 수 없습니다.
인덱스가 디스크에 저장되므로 온디맨드 구체화된 뷰에서 직접 인덱스를 생성할 수 있습니다.
성능
온디맨드 구체화된 뷰는 쿼리의 일부로 계산되지 않고 디스크에서 읽기 때문에 표준 뷰보다 읽기 성능이 뛰어납니다. 파이프라인의 복잡성과 집계되는 데이터의 크기가 커질수록 이러한 성능 이점이 더 커집니다.
MongoDB Atlas UI에서 구체화된 뷰 만들기
이 섹션의 예시에서는 샘플 교육 데이터세트를 사용합니다. MongoDB Atlas 배포에 샘플 데이터세트를 로드하는 방법을 알아보려면 샘플 데이터 로드를 참조하세요.
MongoDB Atlas UI에서 구체화된 뷰를 만들려면 다음 단계를 따르세요.
MongoDB Atlas UI에서 프로젝트의 Clusters 페이지로 이동합니다.
아직 표시되지 않은 경우 탐색 표시줄의 Organizations 메뉴에서 원하는 프로젝트가 포함된 조직을 선택합니다.
아직 표시되지 않은 경우 내비게이션 바의 Projects 메뉴에서 프로젝트를 선택합니다.
아직 표시되지 않은 경우 사이드바에서 Clusters를 클릭합니다.
Clusters(클러스터) 페이지가 표시됩니다.
탭 을 Aggregation 클릭합니다.
드롭다운 메뉴에서 집계 단계를 선택합니다.Select
뷰로 저장하려는 데이터를 집계 단계에서 변환합니다. 사용 가능한 집계 단계에 대해 자세히 알아보려면 집계 단계를 참조하세요.
이 예시에서는 $set
단계가 있는 새 필드를 추가합니다.
Select 드롭다운 메뉴에서
$set
를 선택합니다.집계 파이프라인 편집기에 다음
score
구문을scores
추가하여grades
컬렉션 내 배열의 모든 값에 대한 평균 점수를 만듭니다:{ averageScore: { $avg: "$scores.score" } } MongoDB Atlas는 각 문서에
averageScore
값을 추가합니다.
단계추가 $out
Select 드롭다운 메뉴에서
$out
단계를 선택합니다.파이프라인 결과를
sample_training
데이터베이스의myView
컬렉션에 쓰려면 집계 파이프라인에 다음 구문을 추가하세요.'myView' Save Documents를 클릭합니다.
$out
단계에서는 집계 파이프라인의 결과를 특정 컬렉션에 기록하여 뷰를 만듭니다. 자세한 내용은 $out
을 참조하세요.
컬렉션 목록을 새로고침하여 myView
컬렉션을 확인합니다.
MongoDB Atlas UI에서 myView
컬렉션을 쿼리하는 방법을 알아보려면 MongoDB Atlas 설명서에서 문서 조회, 필터링 및 정렬을 참조하세요.
예시
2019년 1월 말에 기준으로 bakesales
컬렉션에는 항목별 판매 정보가 포함되어 있다고 가정합니다.
db.bakesales.insertMany( [ { date: new ISODate("2018-12-01"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") }, { date: new ISODate("2018-12-02"), item: "Cake - Peanut Butter", quantity: 5, amount: new NumberDecimal("90") }, { date: new ISODate("2018-12-02"), item: "Cake - Red Velvet", quantity: 10, amount: new NumberDecimal("200") }, { date: new ISODate("2018-12-04"), item: "Cookies - Chocolate Chip", quantity: 20, amount: new NumberDecimal("80") }, { date: new ISODate("2018-12-04"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") }, { date: new ISODate("2018-12-05"), item: "Pie - Key Lime", quantity: 3, amount: new NumberDecimal("60") }, { date: new ISODate("2019-01-25"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") }, { date: new ISODate("2019-01-25"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") }, { date: new ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") }, { date: new ISODate("2019-01-26"), item: "Cookies - Chocolate Chip", quantity: 12, amount: new NumberDecimal("48") }, { date: new ISODate("2019-01-26"), item: "Cake - Carrot", quantity: 2, amount: new NumberDecimal("36") }, { date: new ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") }, { date: new ISODate("2019-01-27"), item: "Pie - Chocolate Cream", quantity: 1, amount: new NumberDecimal("20") }, { date: new ISODate("2019-01-27"), item: "Cake - Peanut Butter", quantity: 5, amount: new NumberDecimal("80") }, { date: new ISODate("2019-01-27"), item: "Tarts - Apple", quantity: 3, amount: new NumberDecimal("12") }, { date: new ISODate("2019-01-27"), item: "Cookies - Chocolate Chip", quantity: 12, amount: new NumberDecimal("48") }, { date: new ISODate("2019-01-27"), item: "Cake - Carrot", quantity: 5, amount: new NumberDecimal("36") }, { date: new ISODate("2019-01-27"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") }, { date: new ISODate("2019-01-28"), item: "Cookies - Chocolate Chip", quantity: 20, amount: new NumberDecimal("80") }, { date: new ISODate("2019-01-28"), item: "Pie - Key Lime", quantity: 3, amount: new NumberDecimal("60") }, { date: new ISODate("2019-01-28"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") }, ] );
1. 온디맨드 구체화된 뷰 정의하기
다음 updateMonthlySales
함수는 월별 누적 매출 정보가 포함된 monthlybakesales
구체화된 뷰를 정의합니다. 예시에서 함수는 날짜 매개변수를 사용하여 특정 날짜부터 시작하여 월별 판매 정보만 업데이트합니다.
updateMonthlySales = function(startDate) { db.bakesales.aggregate( [ { $match: { date: { $gte: startDate } } }, { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$date" } }, sales_quantity: { $sum: "$quantity"}, sales_amount: { $sum: "$amount" } } }, { $merge: { into: "monthlybakesales", whenMatched: "replace" } } ] ); };
$match
단계에서는 데이터를 필터링하여startDate
보다 크거나 같은 판매만 처리합니다.$group
단계에서는 판매 정보를 연/월별로 그룹화합니다. 이 단계에서 출력되는 문서의 양식은 다음과 같습니다.{ "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> } $merge
단계는 출력을monthlybakesales
컬렉션에 씁니다.이 단계에서는
_id
필드(샤딩되지 않은 출력 컬렉션의 기본값)를 기반으로 집계 결과의 문서가 컬렉션의 기존 문서와 일치하는지 확인합니다.동일한 연월의 문서가 컬렉션에 이미 존재하는 경우 (즉, 일치하는 경우, 이 단계는 집계 결과의 문서로 기존 문서를 교체합니다.
일치하는 항목이 없는 경우 단계는 집계 결과의 문서를 컬렉션에 삽입합니다(일치하지 않을 때의 기본 동작).
2. 초기 실행 수행
초기 실행의 경우 new
ISODate("1970-01-01")
날짜를 전달할 수 있습니다:
updateMonthlySales(new ISODate("1970-01-01"));
초기 실행 후 monthlybakesales
에는 다음 문서가 포함됩니다. 즉, db.monthlybakesales.find().sort( { _id: 1 } )
는 다음을 반환합니다.
{ "_id" : "2018-12", "sales_quantity" : 41, "sales_amount" : NumberDecimal("506") } { "_id" : "2019-01", "sales_quantity" : 86, "sales_amount" : NumberDecimal("896") }
3. 구체화된 뷰 새로 고침
2019년 2월 첫째 주까지 bakesales
컬렉션이 최신 판매 정보로 업데이트된다고 가정합니다. 구체적으로는 1월과 2월의 추가 판매입니다.
db.bakesales.insertMany( [ { date: new ISODate("2019-01-28"), item: "Cake - Chocolate", quantity: 3, amount: new NumberDecimal("90") }, { date: new ISODate("2019-01-28"), item: "Cake - Peanut Butter", quantity: 2, amount: new NumberDecimal("32") }, { date: new ISODate("2019-01-30"), item: "Cake - Red Velvet", quantity: 1, amount: new NumberDecimal("20") }, { date: new ISODate("2019-01-30"), item: "Cookies - Chocolate Chip", quantity: 6, amount: new NumberDecimal("24") }, { date: new ISODate("2019-01-31"), item: "Pie - Key Lime", quantity: 2, amount: new NumberDecimal("40") }, { date: new ISODate("2019-01-31"), item: "Pie - Banana Cream", quantity: 2, amount: new NumberDecimal("40") }, { date: new ISODate("2019-02-01"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") }, { date: new ISODate("2019-02-01"), item: "Tarts - Apple", quantity: 2, amount: new NumberDecimal("8") }, { date: new ISODate("2019-02-02"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") }, { date: new ISODate("2019-02-02"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") }, { date: new ISODate("2019-02-03"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") } ] )
1월과 2월의 monthlybakesales
데이터를 새로 고치려면 함수를 다시 실행하여 new ISODate("2019-01-01")
부터 집계 파이프라인을 다시 실행합니다.
updateMonthlySales(new ISODate("2019-01-01"));
monthlybakesales
의 내용이 bakesales
컬렉션의 최신 데이터를 반영하도록 업데이트되었습니다. 즉, db.monthlybakesales.find().sort( { _id: 1 } )
가 다음을 반환합니다.
{ "_id" : "2018-12", "sales_quantity" : 41, "sales_amount" : NumberDecimal("506") } { "_id" : "2019-01", "sales_quantity" : 102, "sales_amount" : NumberDecimal("1142") } { "_id" : "2019-02", "sales_quantity" : 15, "sales_amount" : NumberDecimal("284") }
추가 정보
$merge
단계:
동일하거나 다른 데이터베이스의 컬렉션으로 출력할 수 있습니다.
출력 컬렉션이 아직 존재하지 않는 경우 새 컬렉션을 생성합니다.
결과(새 문서 삽입, 문서 병합, 문서 교체, 기존 문서 유지, 작업 실패, 사용자 지정 업데이트 파이프라인으로 문서 처리)를 기존 컬렉션에 통합할 수 있습니다.
샤드된 컬렉션으로 출력할 수 있습니다. 입력 컬렉션도 샤딩할 수 있습니다.
다음 사항에 대해서는 $merge
를 참조하세요.