MongoDB(4) - Cappedコレクション編

今回はMongoDBのCappedコレクションを作成します。

Cappedコレクションは、古いデータを自動で削除してくれるコレクションです。

ログ用のコレクションとしてよく使われます。

Cappedコレクション作成

Cappedコレクションの作成を行います。コレクション名はcap1とします。

Cappedコレクションを作成するときは、createCollectionコマンド実行時にオプションを指定します。

[Mongoシェル]

1
2
3
4
5
> use db1
switched to db db1

> db.createCollection("cap1", {capped:true, size:1024000, max:3})
{ "ok" : 1 }

上記ではサイズの上限(size)が1MB、ドキュメント数の上限(max)が3のCappedコレクションを作成しています。(サイズの単位はbyteとなります)

どちらかの上限に達したときに、古いデータが自動で削除されます。


作成したCappedコレクションの統計情報を確認してみます。

[Mongoシェル]

1
2
3
4
5
6
7
8
9
10
11
12
> db.cap1.stats()
{
"ns" : "db1.cap1",
"size" : 0,
"count" : 0,
"storageSize" : 4096,
"freeStorageSize" : 0,
"capped" : true,
"max" : 3,
"maxSize" : 1024000,
(略)
}

対応するオプションは下記の通りで、正しく設定されていることが確認できます。

  • capped
    Cappedコレクションであるかどうか。
  • max
    ドキュメント数の上限値。
  • maxSize
    コレクションの最大サイズ。

Cappedコレクションの注意点

Cappedコレクションを使用する場合は、下記の3点に注意する必要があります。

  • サイズの上限を変更できない。
    もしサイズを変更したい場合は、新しいCappedコレクションを作成して、データを移行するという手順が必要になります。
  • データの削除・更新ができない。
    データが自動的に削除されていくことが前提にあるため、ドキュメントの削除・更新ができません。
  • シャーディングできない。
    Cappedコレクションをシャーディングすることはできません。
    (シャーディングとは、コレクションごとにデータを複数サーバ分散することができる機能です。)

Cappedコレクションの動作確認

ドキュメントの追加と検索の詳細操作は今後行う予定ですが、Cappedコレクションの動作を確認するためにすこし実行してみます。

[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
28
29
30
31
32
33
34
# ドキュメントを3件追加
> db.cap1.insertOne({age:1})
{
"acknowledged" : true,
"insertedId" : ObjectId("611a3bcdbc6e53b3d72248e0")
}
> db.cap1.insertOne({age:2})
{
"acknowledged" : true,
"insertedId" : ObjectId("611a3bd4bc6e53b3d72248e1")
}
> db.cap1.insertOne({age:3})
{
"acknowledged" : true,
"insertedId" : ObjectId("611a3bd6bc6e53b3d72248e2")

# 全データを確認
> db.cap1.find()
{ "_id" : ObjectId("611a3bcdbc6e53b3d72248e0"), "age" : 1 }
{ "_id" : ObjectId("611a3bd4bc6e53b3d72248e1"), "age" : 2 }
{ "_id" : ObjectId("611a3bd6bc6e53b3d72248e2"), "age" : 3 }

# ドキュメントを1件追加
> db.cap1.insertOne({age:4})
{
"acknowledged" : true,
"insertedId" : ObjectId("611a3bf5bc6e53b3d72248e3")
}

# 全データを確認(古いデータが1件削除されていることが確認できる)
> db.cap1.find()
{ "_id" : ObjectId("611a3bd4bc6e53b3d72248e1"), "age" : 2 }
{ "_id" : ObjectId("611a3bd6bc6e53b3d72248e2"), "age" : 3 }
{ "_id" : ObjectId("611a3bf5bc6e53b3d72248e3"), "age" : 4 }

通常コレクションからCappedコレクションへの変更

通常のコレクションをCappedコレクションに変更することもできます。

cap2というコレクションをいったん作成し、それをCappedコレクションに変更してみます。

[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
28
29
30
31
32
33
34
# 通常コレクションを作成
> db.createCollection("cap2")
{ "ok" : 1 }

# 変更前のコレクションの統計情報を表示
> db.cap2.stats()
{
"ns" : "db1.cap2",
"size" : 0,
"count" : 0,
"storageSize" : 4096,
"freeStorageSize" : 0,
"capped" : false,
(略)
}

# 通常コレクションをCappedコレクションに変更
> db.runCommand({"convertToCapped":"cap2", size:1024, max:1})
{ "ok" : 1 }


# 変更後のコレクションの統計情報を表示
> db.cap2.stats()
{
"ns" : "db1.cap2",
"size" : 0,
"count" : 0,
"storageSize" : 4096,
"freeStorageSize" : 0,
"capped" : true,
"max" : 0,
"maxSize" : 1024,
(略)
}

上記では、サイズの上限が1024バイトでドキュメント数の上限が1のCappedコレクションに変換しています。

統計情報を見ると、cappedオプションがtrueになりサイズの上限(maxSize)が1024になっていることが確認できます。

ただし、ドキュメント数の上限値(max)が1になっていません。

調べたところCappedコレクションへの変更を行うときmaxオプション(ドキュメント数の上限値)は指定できるものの、コレクションに反映することができないという謎仕様があるとのことです。

Cappedコレクションの変更コマンドは使わずに、新規でCappedコレクションを作成しデータの移行をした方が安全かもしれません😅😅