Docs Menu
Docs Home
/ /
Atlas App Services
/ /

MongoDB Atlas でのデータの集計 - 関数

項目一覧

  • Overview
  • データモデル
  • 集計パイプラインの実行
  • Atlas Search によるデータの検索
  • 集計ステージ
  • フィルター ドキュメント
  • グループ ドキュメント
  • プロジェクト ドキュメント フィールド
  • ドキュメントへのフィールドの追加
  • Unwind Array Values

このページの例は、関数で 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}`))

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ステージを使用して、配列フィールドの個々の要素を集計できます。 配列フィールドを展開すると、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 }
}

戻る

書込み