MongoDBで配列要素の平均値を取得するクエリの書き方
MongoDBで配列内の数値の平均を求める方法
MongoDBでは、配列に格納された複数の数値から平均値を算出したいケースがよくあります。例えば、1つのドキュメントの中に複数の点数(Marks)が配列として保存されている場合、その平均点を取得したいことがあります。
このような場合、集計パイプライン(aggregation)と$avg演算子を組み合わせることで、簡単に平均値を求めることができます。$avgは、指定したフィールド(配列の場合はその全要素)の数値の平均を自動的に計算してくれる便利な演算子です。
以下、具体的な手順を見ていきましょう。
1. コレクションを作成し、ドキュメントを挿入する
まず、insertOne()メソッドを使って、配列を含むドキュメントをコレクションに挿入します。
> db.demo584.insertOne({"Marks":[75,50,85,60,80]});{
"acknowledged" : true,
"insertedId" : ObjectId("5e91d827fd2d90c177b5bcc2")
}2. find()メソッドでドキュメントを確認する
次に、find()メソッドを使ってコレクション内のすべてのドキュメントを表示します。
> db.demo584.find().pretty();
このクエリを実行すると、以下のような出力が得られます。
{
"_id" : ObjectId("5e91d827fd2d90c177b5bcc2"),
"Marks" : [
75,
50,
85,
60,
80
]
}3. $avg演算子で配列要素の平均値を取得する
ここが本題です。aggregate()メソッドと$projectステージ、そして$avg演算子を組み合わせることで、配列「Marks」の各要素の平均値を計算できます。
> db.demo584.aggregate([
... { $project: { MarksAvg: { $avg: "$Marks"} } }
... ])このクエリを実行すると、以下のような結果が出力されます。
{ "_id" : ObjectId("5e91d827fd2d90c177b5bcc2"), "MarksAvg" : 70 }解説
このクエリのポイントは以下の通りです。
- aggregate(): 集計処理を行うためのメソッドです。パイプラインと呼ばれる処理の連なりを引数に渡します。
- $project: 出力するフィールドを整形するステージです。ここでは新しいフィールド「MarksAvg」を作成しています。
- $avg: "$Marks": フィールド名の前に「$」を付けて参照します。対象が配列の場合、$avgは自動的にその全要素の平均値を計算します。
上記の例では、(75 + 50 + 85 + 60 + 80) ÷ 5 = 70 という計算が行われ、「MarksAvg」として70が出力されています。
なお、$avgは数値以外の値や欠損値を無視して計算するため、配列内に文字列などが混在している場合でもエラーにはなりません。ただし、正確な平均を求めたい場合は、事前にデータ型を揃えておくことをおすすめします。
-
MongoDBでサブドキュメントの配列をクエリする方法
MongoDBでサブドキュメントの配列をクエリするには、集計パイプラインの$unwindを使用します。$unwindは、配列フィールドを展開し、配列の各要素ごとに個別のドキュメントを生成するステージです。これにより、配列内のサブドキュメントを個別にフィルタリングできるようになります。ここでは、大学の情報を含むコレクションを作成し、その中から特定の条件に一致するサブドキュメントを抽出する手順を解説します。コレクションの作成まず、insertOne()メソッドを使って、サブドキュメントの配列を含むドキュメントを挿入しましょう。> db.demo499.insertOne({... "
-
MongoDBで配列の要素を1つだけ取得する方法|$slice演算子の使い方
MongoDBの$sliceで配列の要素を1つだけ取得する配列から特定の件数の要素だけを取り出したい場合、MongoDBでは$slice演算子を使用します。$sliceはプロジェクション演算子の一種で、指定した件数分の配列要素のみを返すことができます。ここでは、実際にコレクションを作成し、$sliceを使って配列の先頭1件だけを取得する手順を順番に見ていきましょう。サンプルデータの作成まず、insertOne()メソッドを使ってドキュメントをコレクションに挿入します。> db.demo579.insertOne( ... { ... _id : 101, ...