Docs Menu
Docs Home
/
MongoDB Atlas
/ / /

구체화된 보기를 사용하여 Atlas Search 쿼리를 실행하는 방법

이 페이지의 내용

  • purchaseOrders collection 만들기
  • 예정된 트리거 생성
  • 구체화된 뷰에 Atlas Search 인덱스 생성
  • 구체화된 뷰에서 쿼리 실행

이 자습서에서는 샘플 데이터 세트와 새 sample_supplies.purchaseOrders 에서 sample_supplies.sales 컬렉션에 대해 인덱스를 생성하고 쿼리를 실행하는 방법을 설명합니다.

온디맨드 구체화된 뷰는 $merge 집계 파이프라인 단계를 사용하여 만들고 업데이트할 수 있는 컬렉션입니다. 구체화된 뷰에서 Atlas Search 인덱스를 생성한 다음 $search 집계 파이프라인 단계를 사용하여 구체화된 뷰에서 쿼리를 실행할 수 있습니다.

이 튜토리얼에서는 다음 단계를 안내합니다:

  1. sample_supplies 데이터베이스에 purchaseOrders라는 이름의 컬렉션을 생성합니다.

  2. 예약된 트리거 두 개를 생성합니다.

    • updateMonthlySales, 샘플 sample_supplies.sales 컬렉션의 데이터를 사용하여 monthlyPhoneTransactions 구체화된 뷰를 초기화하는 updateMonthlySales 함수가 포함되어 있습니다.

    • updateMonthlyPurchaseOrders, sample_supplies.purchaseOrders 컬렉션의 데이터를 사용하여 monthlyPhoneTransactions 구체화된 뷰를 업데이트하는 updateMonthlyPurchaseOrders 함수가 있습니다.

  3. monthlyPhoneTransactions 구체화된 뷰에 Atlas Search 인덱스를 만듭니다.

  4. monthlyPhoneTransactions 구체화된 뷰에서 쿼리를 실행합니다.

시작하기 전에 Atlas 클러스터가 필수구성 요소에 설명된 요건을 충족하는지 확인하십시오.

Atlas Search 인덱스를 생성하려면 프로젝트에 대한 Project Data Access Admin 이상의 액세스 권한이 있어야 합니다.

트리거를 생성하려면 프로젝트에 대한 Project Owner 이상의 액세스 권한이 있어야 합니다.

1
  1. 터미널 창에서 mongosh를 열고 클러스터에 연결합니다. 연결에 대한 자세한 지침은 mongosh을 통해 연결하기를 참조하세요.

  2. sample_supplies 데이터베이스를 사용합니다.

    use sample_supplies
2

2018년 1월의 새 휴대폰 구매 주문 데이터가 포함된 purchaseOrders 컬렉션을 추가합니다. 다음 명령을 실행합니다.

db.purchaseOrders.insertMany( [
{
saleDate: ISODate("2018-01-23T21:06:49.506Z"),
items: [
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("40.01"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("35.29"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("56.12"),
quantity: 5
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("77.71"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("18.47"),
quantity: 2
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("19.95"),
quantity: 8
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.08"),
quantity: 3
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("14.16"),
quantity: 3
}
],
storeLocation: 'Denver',
customer: {
gender: 'M',
age: 42,
email: 'cauho@witwuta.sv',
satisfaction: 4
},
couponUsed: true,
purchaseMethod: 'Phone'
}
])
db.purchaseOrders.insertMany( [
{
saleDate: ISODate("2018-01-25T10:01:02.918Z"),
items: [
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.05"),
quantity: 10
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("28.31"),
quantity: 9
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("20.95"),
quantity: 3
},
{
name: 'laptop',
tags: [ 'electronics', 'school', 'office' ],
price: Decimal128("866.5"),
quantity: 4
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("33.09"),
quantity: 4
},
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("37.55"),
quantity: 1
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("83.28"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("42.9"),
quantity: 4
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("16.68"),
quantity: 2
}
],
storeLocation: 'Seattle',
customer: { gender: 'M', age: 50, email: 'keecade@hem.uy', satisfaction: 5 },
couponUsed: false,
purchaseMethod: 'Phone'
}
])
3

purchaseOrders 컬렉션을 쿼리하여 새 구매 주문 항목을 확인합니다.

db.purchaseOrders.find().sort( {saleDate: -1} )
{
_id: ObjectId("62434c07d574cd0ce200ba75"),
saleDate: ISODate("2018-01-25T10:01:02.918Z"),
items: [
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.05"),
quantity: 10
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("28.31"),
quantity: 9
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("20.95"),
quantity: 3
},
{
name: 'laptop',
tags: [ 'electronics', 'school', 'office' ],
price: Decimal128("866.5"),
quantity: 4
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("33.09"),
quantity: 4
},
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("37.55"),
quantity: 1
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("83.28"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("42.9"),
quantity: 4
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("16.68"),
quantity: 2
}
],
storeLocation: 'Seattle',
customer: {
gender: 'M',
age: 50,
email: 'keecade@hem.uy',
satisfaction: 5
},
couponUsed: false,
purchaseMethod: 'Phone'
},
{
_id: ObjectId("62434c07d574cd0ce200ba74"),
saleDate: ISODate("2018-01-23T21:06:49.506Z"),
items: [
{
name: 'printer paper',
tags: [ 'office', 'stationary' ],
price: Decimal128("40.01"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("35.29"),
quantity: 2
},
{
name: 'pens',
tags: [ 'writing', 'office', 'school', 'stationary' ],
price: Decimal128("56.12"),
quantity: 5
},
{
name: 'backpack',
tags: [ 'school', 'travel', 'kids' ],
price: Decimal128("77.71"),
quantity: 2
},
{
name: 'notepad',
tags: [ 'office', 'writing', 'school' ],
price: Decimal128("18.47"),
quantity: 2
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("19.95"),
quantity: 8
},
{
name: 'envelopes',
tags: [ 'stationary', 'office', 'general' ],
price: Decimal128("8.08"),
quantity: 3
},
{
name: 'binder',
tags: [ 'school', 'general', 'organization' ],
price: Decimal128("14.16"),
quantity: 3
}
],
storeLocation: 'Denver',
customer: {
gender: 'M',
age: 42,
email: 'cauho@witwuta.sv',
satisfaction: 4
},
couponUsed: true,
purchaseMethod: 'Phone'
}

두 쿼리 결과는 구매 주문 데이터가 2018년 1월에 종료됨을 반영합니다.

다음 절차에서는 트리거를 생성하여 구체화된 뷰를 생성하고 구체화된 뷰를 매일 업데이트하도록 함수를 예약합니다.

1
  1. 아직 표시되지 않은 경우 탐색 표시줄의 Organizations 메뉴에서 프로젝트가 포함된 조직을 선택합니다.

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

  3. 사이드바에서 Services 제목 아래의 Triggers를 클릭합니다.

    트리거 페이지가 표시됩니다.

2
3
UI 필드 이름
구성

Trigger Type

Scheduled0}을 선택합니다.

Name

updateMonthlySales를 지정합니다.

Schedule Type

  1. Basic0}을 선택합니다.

  2. Repeat once by의 경우, Day of the Month를 선택해 원하는 날짜의 값을 설정합니다.

    또한 테스트 목적으로 Repeat once by 드롭다운을 Minute 또는 Hour와 같이 더 자주 발생하는 항목으로 설정할 수 있습니다.

Select An Event Type

Function0}을 선택합니다.

4

이 트리거의 함수는 월간 누적 판매 정보가 포함된 monthlyPhoneTransactions 구체화된 뷰를 정의합니다. 이 함수는 전화로 진행된 판매에 대한 월별 판매 정보를 업데이트합니다.

다음 코드를 함수에 붙여넣습니다.

exports = function(){
var pipeline = [
{ $match: {purchaseMethod: "Phone"} },
{ $unwind: {path: "$items"}},
{ $group: {
_id: { $dateToString:
{ format: "%Y-%m", date: "$saleDate" } },
sales_quantity: { $sum: "$items.quantity"},
sales_price: { $sum: "$items.price"}
}},
{ $set: { sales_price: { $toDouble: "$sales_price"}}},
{ $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } }
]
var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("sales");
return monthlyPhoneTransactions.aggregate(pipeline);
};

이 함수는 다음 집계 파이프라인 단계를 사용하여 monthlyPhoneTransactions 을(를) 업데이트합니다.

  • $match 단계에서는 데이터를 필터링하여 Phone을 통해 완료된 판매만 처리합니다.

  • $group 단계에서는 판매 정보를 연/월별로 그룹화합니다. 이 단계에서는 다음과 같은 형식의 문서가 출력됩니다.

    { "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> }
  • $set 단계는 sales_price 필드의 데이터 유형을 double로 변경합니다. Atlas Search $search 연산자는 Decimal128 데이터 유형을 지원하지 않습니다. sales_price 필드의 데이터 유형을 변경하면 Atlas Search 인덱스를 사용하여 이 필드를 쿼리할 수 있습니다.

  • $merge 단계는 출력을 monthlyPhoneTransactions 컬렉션에 기록합니다.

    이 단계에서는 _id 필드를 기반으로 집계 결과의 문서가 컬렉션의 기존 문서와 일치하는지 확인합니다.

    • Atlas Search가 일치하는 항목을 찾으면(즉, 연/월이 같은 문서가 컬렉션에 이미 존재하는 경우) Atlas Search는 기존 문서를 단계에 지정된 집계 결과의 문서로 바꿉니다.

    • Atlas Search에서 일치하는 항목을 찾지 못하면 Atlas Search는 집계 결과의 문서를 단계에 지정된 대로 컬렉션에 삽입합니다.

5

Function Editor의 오른쪽 하단에 있는 Run 버튼을 클릭하여 monthlyPhoneTransactions 구체화된 뷰를 생성합니다.

Function Editor 하단의 Result 탭은 함수의 실행 상태를 반영합니다. Save Draft를 클릭합니다.

1
  1. 아직 표시되지 않은 경우 탐색 표시줄의 Organizations 메뉴에서 프로젝트가 포함된 조직을 선택합니다.

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

  3. 사이드바에서 Services 제목 아래의 Triggers를 클릭합니다.

    트리거 페이지가 표시됩니다.

2
3
UI 필드 이름
구성

Trigger Type

Scheduled0}을 선택합니다.

Name

updateMonthlySales를 지정합니다.

Schedule Type

  1. Basic0}을 선택합니다.

  2. Repeat once by의 경우, Day of the Month를 선택해 원하는 날짜의 값을 설정합니다.

    또는 테스트 목적으로 Repeat once by 드롭다운이 더 자주 발생하도록(예: Minute 또는 Hour) 설정합니다.

4

updateMonthlyPurchaseOrders 함수는 monthlyPhoneTransactions 구체화된 뷰에 월별 누적 구매 주문 정보를 추가합니다. 이 함수는 전화를 통해 수행된 구매 주문에 대한 월별 구매 주문 정보를 업데이트합니다. 다음 예제에서는 함수를 정의합니다.

exports = function(){
var pipeline = [
{ $match: {purchaseMethod: "Phone"} },
{ $unwind: {path: "$items"}},
{ $group: {
_id: { $dateToString:
{ format: "%Y-%m", date: "$saleDate" } },
sales_quantity: { $sum: "$items.quantity"},
sales_price: { $sum: "$items.price"}
}},
{ $set: { sales_price: { $toDouble: "$sales_price"}}},
{ $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } }
]
var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("purchaseOrders");
return monthlyPhoneTransactions.aggregate(pipeline);
};

updateMonthlyPurchaseOrders 함수는 updateMonthlySales 함수와 동일한 집계 파이프라인 단계를 사용하여 monthlyPhoneTransactions를 업데이트합니다.

5

Function Editor의 오른쪽 하단에 있는 Run 버튼을 클릭하여 monthlyPhoneTransactions 구체화된 뷰를 업데이트합니다.

Function Editor 하단에 있는 Result 탭 은 함수의 실행 상태를 반영합니다.

updateMonthlyPurchaseOrders 함수는 2018년 1월 구매 주문 데이터로 monthlyPhoneTransactions 구체화된 뷰를 새로 고칩니다.

6
7
8

mongosh를 사용하여 monthlyPhoneTransactions 컬렉션을 쿼리하여 업데이트를 확인합니다.

db.monthlyPhoneTransactions.find().sort( { _id: -1} )
{
_id: '2018-01',
sales_quantity: 66,
sales_price: Decimal128("1407.10")
}

monthlyPhoneTransactions 구체화된 뷰는 새로 추가된 데이터를 보여줍니다. 상위 결과는 가장 최근 트랜잭션이 2018 1월에 발생했음을 반영합니다.

9

monthlyPhoneTransactions 컬렉션에 Atlas Search 인덱스를 만듭니다.

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

  2. 아직 표시되지 않은 경우 탐색 표시줄의 Projects 메뉴에서 원하는 프로젝트를 선택합니다.

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

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

2

사이드바, Data Explorer 또는 클러스터 세부 정보 페이지에서 Atlas Search 페이지로 이동할 수 있습니다.

  1. 사이드바에서 Services 제목 아래의 Atlas Search를 클릭합니다.

  2. Select data source 드롭다운에서 클러스터를 선택하고 Go to Atlas Search를 클릭합니다.

    Atlas Search 페이지가 표시됩니다.

  1. cluster의 Browse Collections 버튼을 클릭합니다.

  2. 데이터베이스를 확장하고 컬렉션을 선택합니다.

  3. 컬렉션의 Search Indexes 탭을 클릭합니다.

    Atlas Search 페이지가 표시됩니다.

  1. 클러스터 이름을 클릭합니다.

  2. Atlas Search 탭을 클릭합니다.

    Atlas Search 페이지가 표시됩니다.

3
4
5
  1. Index Name 필드에 monthlyPhoneTransactions를 입력합니다.

  2. Database and Collection 섹션에서 sample_supplies 데이터베이스를 찾고 monthlyPhoneTransactions 컬렉션을 선택합니다.

  3. Next를 클릭합니다.

6
7
8

인덱스가 작성 중임을 보여주는 모달 창이 표시됩니다. Close 버튼을 클릭합니다.

9

새로 생성된 인덱스가 Atlas Search 탭에 나타납니다. 인덱스가 빌드되는 동안 Status 필드는 Building를 읽습니다. 인덱스 빌드가 완료되면 Status 필드에 Active가 표시됩니다.

참고

컬렉션이 클수록 인덱스를 생성하는 데 시간이 더 오래 걸립니다. 인덱스 빌드가 완료되면 이메일 알림을 받게 됩니다.

새로 업데이트되고 인덱싱된 monthlyPhoneTransactions 컬렉션에 대해 쿼리를 실행합니다.

1

터미널 창에서 mongosh 를 열고 클러스터에 연결합니다. 연결에 대한 자세한 지침은 mongosh 를 통한 연결을 참조하세요.

2

mongosh 프롬프트에서 다음 명령을 실행합니다.

use sample_supplies
3

다음 쿼리는 monthlyPhoneTransactions에서 총 판매액이 10000 달러 이상인 개월 수를 계산합니다.

db.monthlyPhoneTransactions.aggregate([
{
$search: {
"index": "monthlySalesIndex",
"range": {
"gt": 10000,
"path": ["sales_price"]
}
}
},
{
$count: 'months_w_over_10000'
},
])

위 쿼리는 4를 반환하는데, 이는 monthlyPhoneTransactions 구체화된 뷰의 전체 월 중 총 매출이 10000달러 이상인 달은 4개월뿐임을 나타냅니다. 이 결과는 sample_supplies.salessample_supplies.purchaseOrders 컬렉션의 데이터를 모두 반영합니다.

전체 집계 파이프라인 설명서는 MongoDB Server 매뉴얼을 참조하세요.

돌아가기

컬렉션 전반