Docs Menu
Docs Home
/
MongoDB Atlas
/ / /

マテリアライズドビューを使用した Atlas Search クエリの実行方法

項目一覧

  • purchaseOrdersコレクションの作成
  • 予定されたトリガーを作成する
  • マテリアライズドビューでの Atlas Search インデックスの作成
  • マテリアライズドビューでのクエリの実行

このチュートリアルでは、インデックスを作成し、 サンプルデータセット sample_supplies.sales コレクションと新しい sample_supplies.purchaseOrders に対してクエリを実行する方法について説明します。

オンデマンドのマテリアライズドビューは、 $merge集計パイプライン ステージを使用して作成および更新するコレクションです。 マテリアライズドビューで Atlas Search インデックスを作成し、 $search集計パイプラインステージを使用してマテリアライズドビューでクエリを実行できます。

このチュートリアルでは、次の手順について説明します。

  1. sample_suppliesデータベースにpurchaseOrdersという名前のコレクションを作成します。

  2. 予定されたトリガーを 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'
}

2 つのクエリ結果は、発注データが2018の 1 月に終了することを反映しています。

次の手順では、マテリアライズドビューを作成するトリガーを作成し、マテリアライズドビューを毎日更新する関数をスケジュールします。

1
  1. まだ表示されていない場合は、プロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。

  2. まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。

  3. サイドバーで、 Services見出しの下のTriggersをクリックします。

    Triggersページが表示されます。

2
3
UI フィールド名
構成

Trigger Type

Scheduled を選択します。

Name

updateMonthlySales を指定します。

Schedule Type

  1. Basic を選択します。

  2. Repeat once byで [ Day of the Monthを選択し、値を希望する日付に設定します。

    あるいは、テスト目的で、 Repeat once byドロップダウンをより頻繁に発生するように設定します( MinuteHourなど)。

Select An Event Type

Function を選択します。

4

この trigger の関数は、累積月間売上情報を含む 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をクリックします。

    Triggersページが表示されます。

2
3
UI フィールド名
構成

Trigger Type

Scheduled を選択します。

Name

updateMonthlySales を指定します。

Schedule Type

  1. Basic を選択します。

  2. Repeat once byで [ Day of the Monthを選択し、値を希望する日付に設定します。

    あるいは、テスト目的で、 Repeat once byドロップダウンをより頻繁に発生するように設定します( MinuteHourなど)

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関数は、 monthlyPhoneTransactionsのマテリアライズドビューを 1 月の2018の発注データで更新します。

6
7
8

mongosh を使用して monthlyPhoneTransactions コレクションをクエリし、更新を確認する。

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

monthlyPhoneTransactionsのマテリアライズドビューには新しく追加されたデータが表示されます。 上位の結果は、最新のトランザクションが 1 月2018に実行されたことを反映しています。

9

monthlyPhoneTransactionsコレクションに Atlas Search インデックスを作成します。

1
  1. まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー

  2. まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。

  3. まだ表示されていない場合は、サイドバーの [Clusters] をクリックします。

    [ Clusters (クラスター) ] ページが表示されます。

2

GoAtlas Searchページには、サイドバー、Data Explorer 、またはクラスターの詳細ページから できます。

  1. サイドバーで、 Services見出しの下のAtlas Searchをクリックします。

  2. [ Select data sourceドロップダウンからクラスターを選択し、[ Go to Atlas Search ] をクリックします。

    Atlas Searchページが表示されます。

  1. クラスターの [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

次のクエリは、合計売上額が10000ドル以上の MongoDBTransactions の月数をカウントします。

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

上記のクエリでは4が返されます。これは、 monthlyPhoneTransactionsマテリアライズドビューのすべての月のうち4か月のみが合計売上額が10000ドル以上であったことを示します。 この結果は、sample_supplies.sales sample_supplies.purchaseOrdersコレクションと コレクションの両方のデータを反映しています。

集計パイプラインの完全なドキュメントについては、 MongoDB Server マニュアル を参照してください。

戻る

コレクション全体