MongoDB Atlas でのデータの集計 - 関数
項目一覧
Overview
このページの例は、関数で MongoDB Query API を使用して Atlas クラスター内のドキュメントを集計する方法を示しています。
MongoDB 集計パイプラインは、コレクション内のすべてのドキュメントを一連のデータ集計ステージを通じて実行し、ドキュメントをフィルタリングして形成し、関連するドキュメントのグループに関するサマリー データを収集することもできます。
注意
サポートされている集計ステージ
Atlas App Services はほぼすべての MongoDB 集計パイプラインのステージと演算子をサポートしていますが、一部のステージと演算子はシステム関数内で実行する必要があります。 詳細については、「集計フレームワークの制限」を参照してください。
データモデル
このページの例では、オンライン ストアでの履歴アイテム販売に関する情報を含む store.purchases
という名前のコレクションを使用します。 各ドキュメントには、アイテムname
や購入したquantity
など、購入したitems
のリストと、アイテムを購入した顧客の一意の ID 値が含まれています。
{ "title": "Purchase", "required": ["_id", "customerId", "items"], "properties": { "_id": { "bsonType": "objectId" }, "customerId": { "bsonType": "objectId" }, "items": { "bsonType": "array", "items": { "bsonType": "object", "required": ["name", "quantity"], "properties": { "name": { "bsonType": "string" }, "quantity": { "bsonType": "int" } } } } } }
スニペットのセットアップ
関数でコード スニペットを使用するには、まず MongoDB コレクション ハンドルをインスタンス化する必要があります。
exports = function() { const mongodb = context.services.get("mongodb-atlas"); const itemsCollection = mongodb.db("store").collection("items"); const purchasesCollection = mongodb.db("store").collection("purchases"); // ... paste snippet here ... }
集計パイプラインの実行
collection.aggregate()
メソッドを使用して集計パイプラインを実行できます。
次の関数スニペットは、 purchases
コレクション内のすべてのドキュメントをcustomerId
値でグループ化し、各カスタマーが購入したアイテムの数と合計購入数を集計します。 ドキュメントをグループ化した後、パイプラインは各カスタマーの ドキュメントに、各カスタマーが一度に購入するアイテムの平均数( averageNumItemsPurchased
)を計算する新しいフィールドを追加します。
const pipeline = [ { "$group": { "_id": "$customerId", "numPurchases": { "$sum": 1 }, "numItemsPurchased": { "$sum": { "$size": "$items" } } } }, { "$addFields": { "averageNumItemsPurchased": { "$divide": ["$numItemsPurchased", "$numPurchases"] } } } ] return purchasesCollection.aggregate(pipeline).toArray() .then(customers => { console.log(`Successfully grouped purchases for ${customers.length} customers.`) for(const customer of customers) { console.log(`customer: ${customer._id}`) console.log(`num purchases: ${customer.numPurchases}`) console.log(`total items purchased: ${customer.numItemsPurchased}`) console.log(`average items per purchase: ${customer.averageNumItemsPurchased}`) } return customers }) .catch(err => console.error(`Failed to group purchases by customer: ${err}`))
Atlas Search によるデータの検索
と collection.aggregate()
集計ステージを使用してコレクションに対して Atlas Search$search
クエリを実行できます。
重要
App Services はシステムユーザーとして$search
操作を実行し、返された検索結果に対してフィールドレベルのルールを適用します。 つまり、ユーザーは読み取りアクセス権のないフィールドを検索できます。 この場合、検索は指定された フィールドに基づいて行われますが、返されたドキュメントには フィールドが含まれません。
exports = async function searchMoviesAboutBaseball() { // 1. Get a reference to the collection you want to search. const movies = context.services .get("mongodb-atlas") .db("sample_mflix") .collection("movies"); // 2. Run an aggregation with $search as the first stage. const baseballMovies = await movies .aggregate([ { $search: { text: { query: "baseball", path: "plot", }, }, }, { $limit: 5, }, { $project: { _id: 0, title: 1, plot: 1, }, }, ]) .toArray(); return baseballMovies; };
{ "plot" : "A trio of guys try and make up for missed opportunities in childhood by forming a three-player baseball team to compete against standard children baseball squads.", "title" : "The Benchwarmers" } { "plot" : "A young boy is bequeathed the ownership of a professional baseball team.", "title" : "Little Big League" } { "plot" : "A trained chimpanzee plays third base for a minor-league baseball team.", "title" : "Ed" } { "plot" : "The story of the life and career of the famed baseball player, Lou Gehrig.", "title" : "The Pride of the Yankees" } { "plot" : "Babe Ruth becomes a baseball legend but is unheroic to those who know him.", "title" : "The Babe" }
注意
$$SEARCH_META 変数の可用性
$$SEARCH_META集計変数は、システムとして実行される関数、または検索されたコレクションの最初のロールのapply_when
式とread
式がtrue
に設定されている場合にのみ使用できます。
これら 2 つのシナリオのいずれも当てはまらない場合、 $$SEARCH_META
は未定義であり、集計は失敗します。
集計ステージ
フィルター ドキュメント
$matchステージを使用すると、標準の MongoDBクエリ構文を使用して受信ドキュメントをフィルタリングできます。
{ "$match": { "<Field Name>": <Query Expression>, ... } }
例
次の$match
ステージでは、受信ドキュメントをフィルタリングして、 graduation_year
フィールドの値が2019
から2024
までの値を持つドキュメントのみを含めます。
{ "$match": { "graduation_year": { "$gte": 2019, "$lte": 2024 }, } }
グループ ドキュメント
$groupステージを使用して、1 つ以上のドキュメントのグループのサマリーデータを集計できます。 MongoDB は_id
式に基づいてドキュメントをグループ化します。
注意
フィールド名の前に$
を付けることで、特定のドキュメント フィールドを参照できます。
{ "$group": { "_id": <Group By Expression>, "<Field Name>": <Aggregation Expression>, ... } }
例
次の$group
ステージでは、ドキュメントをcustomerId
フィールドの値でグループ化し、各customerId
が表示される購入ドキュメントの数を計算します。
{ "$group": { "_id": "$customerId", "numPurchases": { "$sum": 1 } } }
プロジェクト ドキュメント フィールド
$projectステージを使用して、ドキュメントから特定のフィールドを含めたり省略したり、集計演算子を使用して新しいフィールドを計算したりできます。 フィールドを含めるには、その値を1
に設定します。 フィールドを省略するには、その値を0
に設定します。
注意
_id
以外のフィールドを同時に省略して含めることはできません。 _id
以外のフィールドを明示的に含めると、明示的に含めなかったフィールドは自動的に省略されます(その逆も同様)。
{ "$project": { "<Field Name>": <0 | 1 | Expression>, ... } }
例
次の$project
ステージでは、 _id
フィールドが省略され、 customerId
フィールドが含まれ、 numItems
という名前の新しいフィールドが作成されます。ここの値はitems
配列内のドキュメントの数です。
{ "$project": { "_id": 0, "customerId": 1, "numItems": { "$sum": { "$size": "$items" } } } }
ドキュメントへのフィールドの追加
$addFieldsステージを使用して、集計演算子を使用して計算された値を持つ新しいフィールドを追加できます。
注意
$addFields
は$projectに似ていますが、フィールドを含めたり省略したりすることはできません。
例
次の$addFields
ステージでは、 numItems
という名前の新しいフィールドが作成されます。値はitems
配列内のドキュメントの数です。
{ "$addFields": { "numItems": { "$sum": { "$size": "$items" } } } }
Unwind Array Values
$unwindステージを使用して、配列フィールドの個々の要素を集計できます。 配列フィールドを展開すると、MongoDB は配列フィールドの要素ごとに各ドキュメントを 1 回コピーしますが、コピーごとに配列値を配列要素に置き換えます。
{ $unwind: { path: <Array Field Path>, includeArrayIndex: <string>, preserveNullAndEmptyArrays: <boolean> } }
例
次の$unwind
ステージでは、各ドキュメントのitems
配列の要素ごとに新しいドキュメントが作成されます。 また、元の配列内の要素の位置インデックスを指定するitemIndex
というフィールドも新しいドキュメントに追加されます。
{ "$unwind": { "path": "$items", "includeArrayIndex": "itemIndex" } }
purchases
コレクションの次のドキュメントを検討します。
{ _id: 123, customerId: 24601, items: [ { name: "Baseball", quantity: 5 }, { name: "Baseball Mitt", quantity: 1 }, { name: "Baseball Bat", quantity: 1 }, ] }
このドキュメントに例の$unwind
ステージを適用すると、ステージは次の 3 つのドキュメントを出力します。
{ _id: 123, customerId: 24601, itemIndex: 0, items: { name: "Baseball", quantity: 5 } }, { _id: 123, customerId: 24601, itemIndex: 1, items: { name: "Baseball Mitt", quantity: 1 } }, { _id: 123, customerId: 24601, itemIndex: 2, items: { name: "Baseball Bat", quantity: 1 } }