Docs Menu
Docs Home
/
MongoDB 매뉴얼
/ /

온디맨드 구체화된 보기

이 페이지의 내용

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

참고

명확화

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

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

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

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

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

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

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

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

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

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

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

1
  1. 이미 표시되어 있지 않은 경우 탐색 모음의 Organizations 메뉴에서 원하는 프로젝트가 포함된 조직을 선택합니다.

  2. 아직 표시되지 않은 경우 내비게이션 바의 Projects 메뉴에서 프로젝트를 선택합니다.

  3. Clusters 페이지가 아직 표시되지 않은 경우 사이드바에서 Database를 클릭합니다.

    클러스터 페이지가 표시됩니다.

2
  1. 샘플 데이터가 포함된 클러스터의 경우 Browse Collections 을 클릭합니다.

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

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

3
4
5

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

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

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

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

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

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

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

돌아가기

지원되는 작업