マテリアライズドビューを使用した Atlas Search クエリの実行方法
このチュートリアルでは、インデックスを作成し、 サンプルデータセットの sample_supplies.sales
コレクションと新しい sample_supplies.purchaseOrders
に対してクエリを実行する方法について説明します。
オンデマンドのマテリアライズドビューは、 $merge
集計パイプライン ステージを使用して作成および更新するコレクションです。 マテリアライズドビューで Atlas Search インデックスを作成し、 $search
集計パイプラインステージを使用してマテリアライズドビューでクエリを実行できます。
このチュートリアルでは、次の手順について説明します。
sample_supplies
データベースにpurchaseOrders
という名前のコレクションを作成します。予定されたトリガーを 2 つ作成する。
updateMonthlySales
は、サンプルsample_supplies.sales
コレクションのデータを使用してmonthlyPhoneTransactions
のマテリアライズドビューを初期化するupdateMonthlySales
という関数です。updateMonthlyPurchaseOrders
は、sample_supplies.purchaseOrders
コレクションのデータを使用してmonthlyPhoneTransactions
のマテリアライズドビューを更新するupdateMonthlyPurchaseOrders
という関数です。
monthlyPhoneTransactions
のマテリアライズドビューに Atlas Search インデックスを作成します。monthlyPhoneTransactions
のマテリアライズドビューでクエリを実行します。
開始する前に、Atlas クラスターが前提条件 に記載されている要件を満たしていることを確認してください。
Atlas Search インデックスを作成するには、プロジェクトに対するProject Data Access Admin
以上のアクセス権が必要です。
トリガーを作成するには、プロジェクトに対して Project Owner
以上のアクセス権が必要です。
purchaseOrders
コレクションの作成
sample_supplies
データベースに接続します。
ターミナルウィンドウで
mongosh
を開き、クラスターに接続します。接続の詳細な手順については、「mongosh
で接続」を参照してください。sample_supplies
データベースを使用します。use sample_supplies
新しい コレクションを追加します。
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' } ])
新しいコレクションをクエリします。
新しい購入注文エントリを確認するには、 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 月に終了することを反映しています。
予定されたトリガーを作成する
次の手順では、マテリアライズドビューを作成するトリガーを作成し、マテリアライズドビューを毎日更新する関数をスケジュールします。
updateMonthlySales
トリガーの作成
手順
Atlas Atlasで、プロジェクトの {0 ページにGoします。GoTriggers
まだ表示されていない場合は、プロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
サイドバーで、 Services見出しの下のTriggersをクリックします。
Triggersページが表示されます。
関数を作成する
この 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
フィールドに基づいて、集計結果内のドキュメントがコレクション内の既存のドキュメントと一致するかどうかが確認されます。
updateMonthlyPurchaseOrders
トリガーの作成
手順
AtlasGoTriggersAtlas で、プロジェクトの ページにGoします。
まだ表示されていない場合は、プロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
サイドバーで、 Services見出しの下のTriggersをクリックします。
Triggersページが表示されます。
関数を作成する
updateMonthlyPurchaseOrders
関数の仕組み
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
を更新します。
mongosh
を使用して monthlyPhoneTransactions
コレクションをクエリし、更新を確認する。
db.monthlyPhoneTransactions.find().sort( { _id: -1} )
{ _id: '2018-01', sales_quantity: 66, sales_price: Decimal128("1407.10") }
monthlyPhoneTransactions
のマテリアライズドビューには新しく追加されたデータが表示されます。 上位の結果は、最新のトランザクションが 1 月2018に実行されたことを反映しています。
マテリアライズドビューでの Atlas Search インデックスの作成
monthlyPhoneTransactions
コレクションに Atlas Search インデックスを作成します。
AtlasGoClustersAtlas で、プロジェクトの ページにGoします。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
まだ表示されていない場合は、サイドバーの [Clusters] をクリックします。
[ Clusters (クラスター) ] ページが表示されます。
GoAtlas Searchクラスターの ページに します。
GoAtlas Searchページには、サイドバー、Data Explorer 、またはクラスターの詳細ページから できます。
サイドバーで、 Services見出しの下のAtlas Searchをクリックします。
[ Select data sourceドロップダウンからクラスターを選択し、[ Go to Atlas Search ] をクリックします。
Atlas Searchページが表示されます。
クラスターの [Browse Collections] ボタンをクリックします。
データベースを展開し、コレクションを選択します。
コレクションのSearch Indexesタブをクリックします。
Atlas Searchページが表示されます。
クラスタの名前をクリックします。
[Atlas Search] タブをクリックします。
Atlas Searchページが表示されます。
マテリアライズドビューでのクエリの実行
新しくアップデートされ、インデックスが作成されたmonthlyPhoneTransactions
コレクションに対してクエリを実行します。
mongosh
内のクラスターに接続します。
ターミナル ウィンドウでmongosh
を開き、クラスターに接続します。 接続の詳細な手順については、「 mongosh
経由での接続 」を参照してください。
sample_supplies
データベースを使用します。
mongosh
プロンプトで次のコマンドを実行します。
use sample_supplies
sample_supplies.monthlyPhoneTransactions
コレクションに対して簡単な Atlas Search クエリを実行します。
次のクエリは、合計売上額が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 マニュアル を参照してください。