MongoDB(22) - 集計処理(aggregate)③合計(sum)+条件(match)

今回は、検索条件に年齢を加えて集計を行います。

サンプルデータ

以前用意した会社の部、課、従業員データを使用します。

集計処理(aggregate)①データ準備 - https://ailog.site/2021/09/02/2021/0902/

検索条件を追加して課ごとの給料合計

集計時の検索条件を追加する場合は$matchを使います。

従業員コレクション(employee)から、年齢が35歳以上の従業員を対象として課ごとの給料合計を表示します。

[Mongoシェル]

1
2
3
4
5
6
7
> db.employee.aggregate([
{$match: {age: {$gte:35}}},
{$group:{_id:"$k_id", salary_total:{$sum:"$salary"}}}
])
{ "_id" : "ka3", "salary_total" : 550000 }
{ "_id" : "ka4", "salary_total" : 120000 }
{ "_id" : "ka2", "salary_total" : 250000 }

35歳以上の従業員の給料合計を、課ごとに集計できました。

groupとmatchの順番を入れ替える

$group$matchの順番は入れ替えることができます。

先ほど実行した集計に関して、$group$matchの順番を入れ替えて実行してみます。

[Mongoシェル]

1
2
3
4
5
6
> db.employee.aggregate([
{$group:{_id:"$k_id", salary_total:{$sum:"$salary"}}},
{$match: {age: {$gte:35}}}
])

>

何も結果が返ってきませんでした。どうしてでしょうか。


理由は、aggregateではクエリーを上から順番に実行しているためです。

まず、$groupで課ごとに集計作業が実行されて_idとsalary_totalのフィールドのみの結果になります。
次にageフィールドで検索を行っても、ageフィールドがないため検索結果がないということになります。

$group$match順番を変えたり、複数回指定することが可能ですが、その順番には気を付けましょう。

Pythonで操作

上記の集計処理をPythonで行うと、次のようになります。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import pymongo
from pymongo import MongoClient

# MongoDB操作用のインスタンスを作成
client = MongoClient() # [IPとポートを指定する場合] MongoClient('10.200.243.203', 27017')

# データベースの取得
db1 = client.db1

# ①年齢が35歳以上の従業員
# ②課ごとの給料合計表示
docs = db1.employee.aggregate([
{'$match': {'age': {'$gte':35}}},
{'$group':{'_id':'$k_id', 'salary_total':{'$sum':'$salary'}}}])
for doc in docs:
print(doc)

# ①課ごとの給料合計算出
# ②年齢が35歳以上の従業員
docs = db1.employee.aggregate([
{'$group':{'_id':'$k_id', 'salary_total':{'$sum':'$salary'}}},
{'$match': {'age': {'$gte':35}}}])
for doc in docs:
print(doc)

次回は、集計した結果に対して検索を行います。