MongoDB(23) - 集計処理(aggregate)④集計前後に検索

今回は、集計の前後に検索を行ってみます。

サンプルデータ

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

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

集計後に検索

集計後に検索を行います。

具体的には①課ごとに給料合計を集計し、②総務課を抽出します。

groupにフィールドを指定する場合はフィールド名の先頭に$を付けますが、matchにフィールドを指定する場合はフィールド名の先頭に$をつける必要はありません。

[Mongoシェル]

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

> { "_id" : "ka1", "salary_total" : 400000 }

集計結果への検索を行うことができました。

集計の前後に検索

集計前と集計後に検索を行います。

具体的には①30歳以上の従業員を検索し、②課ごとに給料合計を集計し、③開発1課を抽出します。

[Mongoシェル]

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

> { "_id" : "ka3", "salary_total" : 550000 }

集計の前と後に検索を行うことができました。

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
25
26
27
28
import pymongo
from pymongo import MongoClient

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

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

# ①課ごとに給料合計を集計
# ②総務課を抽出
docs = db1.employee.aggregate([
{'$group':{'_id':'$k_id', 'salary_total':{'$sum':'$salary'}}},
{'$match': {'_id': 'ka1'}}
])
for doc in docs:
print(doc)

# ①30歳以上の従業員
# ②課ごとに給料合計を集計
# ③開発1課を抽出
docs = db1.employee.aggregate([
{'$match': {'age': {'$gte':30}}},
{'$group':{'_id':'$k_id', 'salary_total':{'$sum':'$salary'}}},
{'$match': {'_id': 'ka3'}}
])
for doc in docs:
print(doc)

次回は、最大値・最小値・平均値の集計を行います。

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)

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

MongoDB(21) - 集計処理(aggregate)②合計($sum)

今回は、簡単な集計として従業員の課ごとの給料合計を集計してみます。

サンプルデータ

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

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

課ごとの給料合計

指定したフィールドで集計を行うためにはaggregateの引数に$groupを指定し、集計条件を設定します。

合計を表示するためには$sumを集計条件に指定します。

従業員コレクション(employee)から、課ごとの給料合計を表示してみます。

[Mongoシェル]

1
2
3
4
5
6
7
> db.employee.aggregate([
{$group:{_id:"$k_id", salary_total:{$sum:"$salary"}}}
])
{ "_id" : "ka1", "salary_total" : 400000 }
{ "_id" : "ka3", "salary_total" : 750000 }
{ "_id" : "ka4", "salary_total" : 220000 }
{ "_id" : "ka2", "salary_total" : 250000 }

集計条件の設定内容は以下の通りです。

  • _idに指定したフィールド($k_id)で集計を行います。
    フィールドは“$フィールド名”と先頭に$を追加して指定します。
    SQLだと[ group by k_id ]の意味です。
  • salary_totalは集計結果のフィールド名です。
    SQLだと[ select salary_total ]の意味です。
  • 集計関数として$sumを指定し、集計するフィールドは“$フィールド名”と先頭に$を追加して設定します。
    SQLだと[ sum(salary) ]の意味です。

SQLに慣れている人ですと、フィールド名の先頭に$をつけたり、記述がやや込み入って見えたりするかもしれませんが、1つ1つ対応関係を確認すれば読み解けるかと思います。

Pythonで操作

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

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
import pymongo
from pymongo import MongoClient

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

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

# 課ごとの給料合計表示
docs = db1.employee.aggregate([{'$group':{'_id':'$k_id', 'salary_total':{'$sum':'$salary'}}}])
for doc in docs:
print(doc)

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

MongoDB(20) - 集計処理(aggregate)①データ準備

今回から、MongoDBでの集計処理(aggretate)を行っていきます。

今回は前準備として集計動作確認用のデータを作成します。

サンプルデータ

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

データのイメージは次の通りです。

  • 課は1つの部に所属します。
  • 従業員は1つの課に所属します。
  • 従業員は1つの役職を持ちます。

部のデータ作成

部のデータを作成します。コレクション名はdepartmentです。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
> db.department.insertMany([
{b_id:"bu1", name:"総務部"},
{b_id:"bu2", name:"企画部"},
{b_id:"bu3", name:"開発部"}
])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("612f075468110fe533ed9d16"),
ObjectId("612f075468110fe533ed9d17"),
ObjectId("612f075468110fe533ed9d18")
]
}

> db.department.find({}, {_id:0})
{ "b_id" : "bu1", "name" : "総務部" }
{ "b_id" : "bu2", "name" : "企画部" }
{ "b_id" : "bu3", "name" : "開発部" }

課のデータ作成

課のデータを作成します。コレクション名はdivisionです。

b_idフィールドは所属する部署を表します。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> db.division.insertMany([
{k_id:"ka1", b_id:"bu1", name:"総務課"},
{k_id:"ka2", b_id:"bu2", name:"企画課"},
{k_id:"ka3", b_id:"bu3", name:"開発1課"},
{k_id:"ka4", b_id:"bu3", name:"開発2課"}
])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("612f07b568110fe533ed9d19"),
ObjectId("612f07b568110fe533ed9d1a"),
ObjectId("612f07b568110fe533ed9d1b"),
ObjectId("612f07b568110fe533ed9d1c")
]
}

> db.division.find({}, {_id:0})
{ "k_id" : "ka1", "b_id" : "bu1", "name" : "総務課" }
{ "k_id" : "ka2", "b_id" : "bu2", "name" : "企画課" }
{ "k_id" : "ka3", "b_id" : "bu3", "name" : "開発1課" }
{ "k_id" : "ka4", "b_id" : "bu3", "name" : "開発2課" }

役職のデータ作成

役職のデータを作成します。コレクション名はpositionです。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> db.position.insertMany([
{p_id:"po1", name:"社長"},
{p_id:"po2", name:"部長"},
{p_id:"po3", name:"課長"},
{p_id:"po4", name:"一般社員"}
])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("612f07d768110fe533ed9d1d"),
ObjectId("612f07d768110fe533ed9d1e"),
ObjectId("612f07d768110fe533ed9d1f"),
ObjectId("612f07d768110fe533ed9d20")
]
}

> db.position.find({}, {_id:0})
{ "p_id" : "po1", "name" : "社長" }
{ "p_id" : "po2", "name" : "部長" }
{ "p_id" : "po3", "name" : "課長" }
{ "p_id" : "po4", "name" : "一般社員" }

従業員のデータ作成

従業員のデータを作成します。コレクション名はemployeeです。

k_idフィールドは所属する課を表し、p_idは役職を表します。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
> db.employee.insertMany([
{e_id:"emp001", k_id:"ka1", p_id:"po1", name:"高山", age:31, salary:400000},
{e_id:"emp002", k_id:"ka2", p_id:"po2", name:"生駒", age:37, salary:250000},
{e_id:"emp003", k_id:"ka3", p_id:"po3", name:"嘉喜", age:23, salary:200000},
{e_id:"emp004", k_id:"ka4", p_id:"po4", name:"与田", age:33, salary:100000},
{e_id:"emp005", k_id:"ka3", p_id:"po4", name:"松田", age:35, salary:550000},
{e_id:"emp006", k_id:"ka4", p_id:"po4", name:"菅井", age:45, salary:120000}
])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("612f07f568110fe533ed9d21"),
ObjectId("612f07f568110fe533ed9d22"),
ObjectId("612f07f568110fe533ed9d23"),
ObjectId("612f07f568110fe533ed9d24"),
ObjectId("612f07f568110fe533ed9d25"),
ObjectId("612f07f568110fe533ed9d26")
]
}

> db.employee.find({}, {_id:0})
{ "e_id" : "emp001", "k_id" : "ka1", "p_id" : "po1", "name" : "高山", "age" : 31, "salary" : 400000 }
{ "e_id" : "emp002", "k_id" : "ka2", "p_id" : "po2", "name" : "生駒", "age" : 37, "salary" : 250000 }
{ "e_id" : "emp003", "k_id" : "ka3", "p_id" : "po3", "name" : "嘉喜", "age" : 23, "salary" : 200000 }
{ "e_id" : "emp004", "k_id" : "ka4", "p_id" : "po4", "name" : "与田", "age" : 33, "salary" : 100000 }
{ "e_id" : "emp005", "k_id" : "ka3", "p_id" : "po4", "name" : "松田", "age" : 35, "salary" : 550000 }
{ "e_id" : "emp006", "k_id" : "ka4", "p_id" : "po4", "name" : "菅井", "age" : 45, "salary" : 120000 }

以上で、集計動作確認用のデータの準備ができました。


次回は、簡単な集計として従業員の課ごとの給料合計を集計してみます。

MongoDB(19) - ドキュメント削除編

今回は、ドキュメントの削除を行います。

サンプルデータ

次のようなデータをcol1コレクションに設定します。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> db.col1.insertMany([{name:"白石", age:29},
{name:"嘉喜", age:19},
{name:"西野", age:28},
{name:"武元", age:5}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("612d8ecb86b5a5660ce2fd20"),
ObjectId("612d8ecb86b5a5660ce2fd21"),
ObjectId("612d8ecb86b5a5660ce2fd22"),
ObjectId("612d8ecb86b5a5660ce2fd23")
]
}

> db.col1.find()
{ "_id" : ObjectId("612d8ecb86b5a5660ce2fd20"), "name" : "白石", "age" : 29 }
{ "_id" : ObjectId("612d8ecb86b5a5660ce2fd21"), "name" : "嘉喜", "age" : 19 }
{ "_id" : ObjectId("612d8ecb86b5a5660ce2fd22"), "name" : "西野", "age" : 28 }
{ "_id" : ObjectId("612d8ecb86b5a5660ce2fd23"), "name" : "武元", "age" : 5 }

1件削除

ドキュメントを1件削除する場合は、deleteOneを使います。

第1引数に検索条件を指定します。

[Mongoシェル]

1
2
3
4
5
6
7
> db.col1.deleteOne({name:"西野"})
{ "acknowledged" : true, "deletedCount" : 1 }

> db.col1.find()
{ "_id" : ObjectId("612d8ecb86b5a5660ce2fd20"), "name" : "白石", "age" : 29 }
{ "_id" : ObjectId("612d8ecb86b5a5660ce2fd21"), "name" : "嘉喜", "age" : 19 }
{ "_id" : ObjectId("612d8ecb86b5a5660ce2fd23"), "name" : "武元", "age" : 5 }

nameが”西野”のドキュメントだけが削除されました。

もし検索条件に複数のドキュメントが一致しても、削除されるのは1件のみとなります。

複数削除

ドキュメントを複数削除する場合は、deleteManyを使います。

第1引数に検索条件を指定します。

今回は、検索条件を指定せずに全件削除してみます。

[Mongoシェル]

1
2
3
4
5
> db.col1.deleteMany({})
{ "acknowledged" : true, "deletedCount" : 3 }

> db.col1.find()

問題なく全件削除されました。

コレクション内のドキュメントを全件削除する場合は、deleteOneや一括高速処理のBulkで削除するよりもコレクション自体を削除したほうが速いとのことなので、コレクション名.drop()の方を使いましょう。

Pythonで操作

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

[ソースコード]

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

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

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

# 1件削除
db1.col1.delete_one({'name':'西野'})

# 結果表示
for doc in db1.col1.find():
print(doc)

# 複数削除
db1.col1.delete_many({})

# 結果表示
for doc in db1.col1.find():
print(doc)

次回は、データの集計(aggregate)を行います。

MongoDB(18) - 更新編 (データがない場合は登録/データがある場合は更新)

MongoDBでは、updateとinsertを合わせた処理としてupsertという処理ができます。

検索条件に一致した場合はupdateを行い、一致しない場合はinsertを行います。

サンプルデータ

次のようなデータをcol1コレクションに設定します。

[Mongoシェル]

1
2
3
4
5
6
7
8
> db.col1.insertOne({name:"白石", age:29})
{
"acknowledged" : true,
"insertedId" : ObjectId("612c0e58381137ed71b344c5")
}

> db.col1.find()
{ "_id" : ObjectId("612c0e58381137ed71b344c5"), "name" : "白石", "age" : 29 }

upsertで更新

updateOne、updateManyの第3引数に{upsert:true}を指定すると、upsert処理が実行できます。

まずは、upsert処理でデータを更新してみます。

[Mongoシェル]

1
2
3
4
5
> db.col1.updateOne({name:"白石"}, {$set:{sex:"女"}}, {upsert:true})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.col1.find()
{ "_id" : ObjectId("612c0e58381137ed71b344c5"), "name" : "白石", "age" : 29, "sex" : "女" }

検索条件に合致するドキュメントがあったので、そのデータにsexフィールドが追加されました。

upsertで追加

次に、upsert処理でデータを追加してみます。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
> db.col1.updateOne({name:"高山"}, {$set:{sex:"男"}}, {upsert:true})
{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("612c0ea8d7d19d218ba03157")
}

> db.col1.find()
{ "_id" : ObjectId("612c0e58381137ed71b344c5"), "name" : "白石", "age" : 29, "sex" : "女" }
{ "_id" : ObjectId("612c0ea8d7d19d218ba03157"), "name" : "高山", "sex" : "男" }

nameが”高山”のドキュメントがなかったので、新しいドキュメントが追加されました。

upsertで追加されるデータは、検索条件と更新内容に指定したフィールドのみとなります。

Pythonで操作

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

(upsertの指定の仕方にご注意ください。)

[ソースコード]

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

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

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

# upsertで更新
db1.col1.update_one({'name':'白石'}, {'$set':{'sex':'女'}}, upsert=True)

# 結果表示
for doc in db1.col1.find():
print(doc)

# upsertで追加
db1.col1.update_one({'name':'高山'}, {'$set':{'sex':'男'}}, upsert=True)

# 結果表示
for doc in db1.col1.find():
print(doc)

次回は、ドキュメントの削除を行います。

MongoDB(17) - 更新編 (フィールド名の変更)

MongoDBでは、大量のデータを保持することが多いため、どうしてもディスク容量が大きくなる傾向があります。

フィールド名を短くすると、ディスク容量を節約することができます。

というわけで今回は、フィールド名の変更を行います。

サンプルデータ

次のようなデータをcol1コレクションに設定します。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> db.col1.insertMany([{name:'白石'},
{name:'平手'},
{name:'松田'}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("612ad81fd1f2105c574196f1"),
ObjectId("612ad81fd1f2105c574196f2"),
ObjectId("612ad81fd1f2105c574196f3")
]
}

> db.col1.find()
{ "_id" : ObjectId("612ad81fd1f2105c574196f1"), "name" : "白石" }
{ "_id" : ObjectId("612ad81fd1f2105c574196f2"), "name" : "平手" }
{ "_id" : ObjectId("612ad81fd1f2105c574196f3"), "name" : "松田" }

フィールド名の変更

フィールド名の変更には$renameを使います。

第1引数には検索条件を指定し、第2引数には$rename古いフィールド名:”新しいフィールド名”を設定します。

新旧のフィールド名は、カンマで区切り複数指定することもできます。

[Mongoシェル]

1
2
3
4
5
6
7
> db.col1.updateMany({}, {$rename:{name:"lastName"}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }

> db.col1.find()
{ "_id" : ObjectId("612ad81fd1f2105c574196f1"), "lastName" : "白石" }
{ "_id" : ObjectId("612ad81fd1f2105c574196f2"), "lastName" : "平手" }
{ "_id" : ObjectId("612ad81fd1f2105c574196f3"), "lastName" : "松田" }

nameフィールドをlastNameフィールドに変更することができました。

Pythonで操作

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

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pymongo
from pymongo import MongoClient

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

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

# フィールド名の変更
db1.col1.update_many({}, {'$rename':{'name':'lastName'}})

# 結果表示
for doc in db1.col1.find():
print(doc)

次回は、データがない場合は登録データがある場合は更新する処理を行います。

MongoDB(16) - 更新編 (配列への要素追加 / オブジェクトへのフィールド追加)

今回は、配列への要素追加とオブジェクトへのフィールド追加を行います。

サンプルデータ

次のようなデータをcol1コレクションに設定します。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> db.col1.insertOne({name:'高山',
age:20,
skill:['SQL', 'DB2', 'Oracle'],
child:[{name:'めい', age:7},
{name:'まい', age:5}]})
{
"acknowledged" : true,
"insertedId" : ObjectId("6129980b545059c91cb01b60")
}

> db.col1.find()
{ "_id" : ObjectId("6129980b545059c91cb01b60"),
"name" : "高山",
"age" : 20,
"skill" : [ "SQL", "DB2", "Oracle" ],
"child" : [ { "name" : "めい", "age" : 7 },
{ "name" : "まい", "age" : 5 } ] }

配列への要素追加

新しいスキル(skill)として”Python”を追加します。

“フィールド名.要素数”とすることで、配列の中の要素を更新することができます。

要素数は0から順番に指定します。

指定する番号の要素に値がある場合はその値を更新し、値がない場合は要素が追加されます。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
> db.col1.updateOne({name:"高山"}, {$set:{"skill.4":"Python"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.col1.find()
{ "_id" : ObjectId("6129980b545059c91cb01b60"),
"name" : "高山",
"age" : 20,
"skill" : [ "SQL", "DB2", "Oracle", null, "Python" ],
"child" : [ { "name" : "めい", "age" : 7 },
{ "name" : "まい", "age" : 5 } ] }

新しく要素を追加した結果、未設定の要素ができるとnullが設定されます。(上記の例では”skill”の0から数えて3番目の要素)

オブジェクトへのフィールド追加

childという配列の中の0番目のオブジェクトに、性別を追加します。

“フィールド名.要素数.フィールド名”とすることで、オブジェクトへフィールドを追加することができます。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
> db.col1.updateOne({name:"高山"}, {$set:{"child.0.sex":"女"}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.col1.find()
{ "_id" : ObjectId("6129980b545059c91cb01b60"),
"name" : "高山",
"age" : 20,
"skill" : [ "SQL", "DB2", "Oracle", null, "Python" ],
"child" : [ { "name" : "めい", "age" : 7, "sex" : "女" },
{ "name" : "まい", "age" : 5 } ] }

Pythonで操作

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

[ソースコード]

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

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

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

# 配列への要素追加
db1.col1.update_one({'name':'高山'}, {'$set':{'skill.4':'Python'}})

# 結果表示
for doc in db1.col1.find():
print(doc)

# オブジェクトへのフィールド追加
db1.col1.update_one({'name':'高山'}, {'$set':{'child.0.sex':'女'}})

# 結果表示
for doc in db1.col1.find():
print(doc)

次回は、フィールド名の変更を行います。

MongoDB(15) - 更新編(ドキュメント入れ替え・フィールド追加)

今回は、ドキュメントの入れ替えとフィールドの追加を行います。

サンプルデータ

次のようなデータをcol1コレクションに設定します。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> db.col1.insertOne({name:'高山', age:20})
{
"acknowledged" : true,
"insertedId" : ObjectId("61282d03a951707ba58eecdd")
}
> db.col1.insertOne({name:'生田', age:11})
{
"acknowledged" : true,
"insertedId" : ObjectId("61282d0aa951707ba58eecde")
}
> db.col1.insertOne({name:'菅井', age:34})
{
"acknowledged" : true,
"insertedId" : ObjectId("61282d12a951707ba58eecdf")
}
> db.col1.find()
{ "_id" : ObjectId("61282d03a951707ba58eecdd"), "name" : "高山", "age" : 20 }
{ "_id" : ObjectId("61282d0aa951707ba58eecde"), "name" : "生田", "age" : 11 }
{ "_id" : ObjectId("61282d12a951707ba58eecdf"), "name" : "菅井", "age" : 34 }

ドキュメント入れ替え

ドキュメントの入れ替えとは、_id(主キー)以外のフィールドを削除して、新しいフィールドを入れ直すことです。

ドキュメントの入れ替えにはreplaceOneを使います。(replaceManyはありません。)

第1引数には検索条件を指定し、第2引数には更新内容を指定します。

[Mongoシェル]

1
2
3
4
5
6
7
> db.col1.replaceOne({name:"生田"}, {firstName:"ほのか", lastName:"田村", age:30})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.col1.find()
{ "_id" : ObjectId("61282d03a951707ba58eecdd"), "name" : "高山", "age" : 20 }
{ "_id" : ObjectId("61282d0aa951707ba58eecde"), "firstName" : "ほのか", "lastName" : "田村", "age" : 30 }
{ "_id" : ObjectId("61282d12a951707ba58eecdf"), "name" : "菅井", "age" : 34 }

フィールド追加

replaceOneを使えば、フィールドの追加と削除ができますが1フィールドだけ追加したい場合は少々手間です。

updateを使えば、容易にフィールドを追加することができます。

第1引数には検索条件を指定し、第2引数には$setを使い追加フィールドを設定します。

[Mongoシェル]

1
2
3
4
5
6
7
> db.col1.updateOne({name:"菅井"}, {$set:{height:163, weight:45}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.col1.find()
{ "_id" : ObjectId("61282d03a951707ba58eecdd"), "name" : "高山", "age" : 20 }
{ "_id" : ObjectId("61282d0aa951707ba58eecde"), "firstName" : "ほのか", "lastName" : "田村", "age" : 30 }
{ "_id" : ObjectId("61282d12a951707ba58eecdf"), "name" : "菅井", "age" : 34, "height" : 163, "weight" : 45 }

Pythonで操作

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

[ソースコード]

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

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

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

# ドキュメント入れ替え
db1.col1.replace_one({'name':'生田'}, {'firstName':'ほのか', 'lastName':'田村', 'age':30})

# 結果表示
for doc in db1.col1.find():
print(doc)

# フィールド追加
db1.col1.update_one({'name':'菅井'}, {'$set':{'height':163, 'weight':45}})

# 結果表示
for doc in db1.col1.find():
print(doc)

次回は、配列への要素追加とオブジェクトへのフィールド追加を行います。

MongoDB(14) - 更新編

今回からは、MongoDBの更新に関する動作を確認していきます。

サンプルデータ

次のようなデータをcol1コレクションに設定します。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> db.col1.insertOne({name:'高山', age:20})
{
"acknowledged" : true,
"insertedId" : ObjectId("6126f663f49ea66243206a1b")
}

> db.col1.insertOne({name:'生田', age:11})
{
"acknowledged" : true,
"insertedId" : ObjectId("6126f663f49ea66243206a1c")
}

> db.col1.insertOne({name:'菅井', age:34})
{
"acknowledged" : true,
"insertedId" : ObjectId("6126f663f49ea66243206a1d")
}

> db.col1.find()
{ "_id" : ObjectId("6126f663f49ea66243206a1b"), "name" : "高山", "age" : 20 }
{ "_id" : ObjectId("6126f663f49ea66243206a1c"), "name" : "生田", "age" : 11 }
{ "_id" : ObjectId("6126f663f49ea66243206a1d"), "name" : "菅井", "age" : 34 }

1件更新

ドキュメントを1件更新する場合は、updateOneを使います。

第1引数には検索条件を指定し、第2引数には$setを使い更新内容を設定します。

[Mongoシェル]

1
2
3
4
5
6
7
> db.col1.updateOne({name:"高山"}, {$set:{age:21}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

> db.col1.find()
{ "_id" : ObjectId("6126f663f49ea66243206a1b"), "name" : "高山", "age" : 21 }
{ "_id" : ObjectId("6126f663f49ea66243206a1c"), "name" : "生田", "age" : 11 }
{ "_id" : ObjectId("6126f663f49ea66243206a1d"), "name" : "菅井", "age" : 34 }

nameが“高山”のドキュメントに関して、ageを21に更新しました。

updateOneでは、検索条件に一致するデータが複数あっても、1件しか更新されません。

複数件更新

ドキュメントを複数更新する場合は、updateManyを使います。

第1引数には検索条件を指定し、第2引数には$setを使い更新内容を設定します。

[Mongoシェル]

1
2
3
4
5
6
7
> db.col1.updateMany({}, {$set:{age:50}})
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }

> db.col1.find()
{ "_id" : ObjectId("6126f663f49ea66243206a1b"), "name" : "高山", "age" : 50 }
{ "_id" : ObjectId("6126f663f49ea66243206a1c"), "name" : "生田", "age" : 50 }
{ "_id" : ObjectId("6126f663f49ea66243206a1d"), "name" : "菅井", "age" : 50 }

全てのドキュメントに対して、ageを50に変更しました。

検索条件になにも設定しないと、全てのドキュメントが更新されます。

Pythonで操作

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

[ソースコード]

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

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

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

# 1件更新
db1.col1.update_one({'name':'高山'}, {'$set':{'age':21}})

# 結果表示
for doc in db1.col1.find():
print(doc)

# 複数件更新
db1.col1.update_many({}, {'$set':{'age':50}})

# 結果表示
for doc in db1.col1.find():
print(doc)

次回は、ドキュメントの入れ替えとフィールドの追加を行います。