문서 메뉴
문서 홈
/
MongoDB 매뉴얼
/ /

온디맨드 구체화된 보기

이 페이지의 내용

  • 표준 뷰와 비교
  • MongoDB Atlas UI에서 구체화된 뷰 만들기
  • 예제
  • 추가 정보

참고

명확화

이 페이지에서는 온디맨드 구체화된 뷰에 대해 설명합니다. 표준 뷰에 대한 설명은 뷰를 참조하세요.

뷰 유형 간의 차이점을 이해하려면 표준 보기와의 비교를 참조하세요.

온디맨드 구체화된 뷰는 디스크에 저장되고 디스크에서 읽히는 미리 계산된 애그리게이션 파이프라인 결과입니다. 온디맨드 구체화된 뷰는 일반적으로 $merge 또는 $out 단계의 결과물입니다.

MongoDB는 표준 뷰온디맨드 구체화된 뷰의 두 가지 뷰 유형을 제공합니다. 두 뷰 유형 모두 aggregation pipeline에서 결과를 반환합니다.

  • 표준 뷰는 뷰를 읽을 때 계산되며 디스크에 저장되지 않습니다.

  • 온디맨드 구체화된 뷰는 디스크에 저장되고 디스크에서 읽혀집니다. $merge 또는 $out 단계를 사용하여 저장된 데이터를 업데이트합니다.

표준 뷰는 기본 컬렉션의 인덱스를 사용합니다. 따라서 표준 뷰에서 직접 인덱스를 생성, 삭제 또는 다시 작성할 수 없으며 뷰에서 인덱스 목록을 가져올 수 없습니다.

인덱스가 디스크에 저장되므로 온디맨드 구체화된 뷰에서 직접 인덱스를 생성할 수 있습니다.

온디맨드 구체화된 뷰는 쿼리의 일부로 계산되지 않고 디스크에서 읽기 때문에 표준 뷰보다 읽기 성능이 뛰어납니다. 파이프라인의 복잡성과 집계되는 데이터의 크기가 커질수록 이러한 성능 이점이 더 커집니다.

이 섹션의 예에서는 샘플 영화 데이터세트를 사용합니다. MongoDB Atlas 배포서버에 샘플 데이터세트를 로드하는 방법을 알아보려면 샘플 데이터 로드를 참조하세요.

MongoDB Atlas UI에서 구체화된 뷰를 만들려면 다음 단계를 따르세요.

1
  1. MongoDB Atlas UI의 Database 사이드바에서 버튼을 클릭합니다.

  2. 샘플 데이터가 포함된 데이터베이스 배포서버의 경우 Browse Collections을 클릭합니다.

  3. 왼쪽 탐색 창에서 sample_training 데이터베이스를 선택합니다.

  4. grades 컬렉션을 선택합니다.

2
3
4

뷰로 저장하려는 데이터를 애그리게이션 단계에서 변환합니다. 사용 가능한 애그리게이션 단계에 대해 자세히 알아보려면 애그리게이션 단계를 참조하세요.

이 예제에서는 $set 단계가 있는 새 필드를 추가합니다.

  1. Select 드롭다운 메뉴에서 $set 를 선택합니다.

  2. 애그리게이션 파이프라인 편집기에 다음 score 구문을 scores 추가하여 grades 컬렉션 내 배열의 모든 값에 대한 평균 점수를 만듭니다:

    {
    averageScore: { $avg: "$scores.score" }
    }

    MongoDB Atlas는 각 문서에 averageScore 값을 추가합니다.

5
6
  1. Select 드롭다운 메뉴에서 $out 단계를 선택합니다.

  2. 파이프라인 결과를 sample_training 데이터베이스의 myView 컬렉션에 쓰려면 애그리게이션 파이프라인에 다음 구문을 추가하세요.

    'myView'
  3. Save Documents를 클릭합니다.

$out 단계에서는 aggregation pipeline의 결과를 특정 컬렉션에 기록하여 뷰를 만듭니다. 자세한 내용은 $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") },
] );

다음 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 필드(샤딩되지 않은 출력 컬렉션의 기본값)를 기반으로 애그리게이션 결과의 문서가 컬렉션의 기존 문서와 일치하는지 확인합니다.

초기 실행의 경우 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") }

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")부터 aggregation pipeline을 다시 실행합니다.

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를 참조하세요.

← 뷰에 지원되는 작업