MongoDBデータ操作(DB, Collection, Document)

MongoDBは、ドキュメント指向のNoSQLデータベースです。RDBと違いトランザクションが無いため、大量データを高速に処理できるといったメリットがあります。ここではDockerでMongoDBを立ち上げて、基本的なデータ操作方法を確認します。

MongoDBの構成要素

RDBと比較すると以下のようになります。

RDB MongoDB
Database Database
Table Collection
Record Document
Column Field

docker-composeでMongoDB立ち上げ

docker-compose.yml

公式イメージを利用します。

docker-compose.yml に以下内容を記述します。

version: '3.1'

services:

  mongo:
    image: mongo
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example
    ports:
      - 27017:27017
    volumes:
      - ./db:/data/db

  mongo-express:
    image: mongo-express
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: example

立ち上げ

$ docker-compose up -d
Starting mongodb_mongo-express_1 ... done
Starting mongodb_mongo_1         ... done

以下のようにRedisが立ち上がりました。

$ docker-compose ps
         Name                        Command               State            Ports          
-------------------------------------------------------------------------------------------
mongodb_mongo-express_1   tini -- /docker-entrypoint ...   Up      0.0.0.0:8081->8081/tcp  
mongodb_mongo_1           docker-entrypoint.sh mongod      Up      0.0.0.0:27017->27017/tcp

GUIツール( mongo-express )へアクセス

ブラウザで http://0.0.0.0:8081 にアクセスするとGUIツールであるmongo-expressが表示されます。

784-server-mongodb-introduction_01.png

ターミナルからMongoDBに接続

Macに Mongo shell をインストールします。

brew tap mongodb/brew
brew install mongodb-community-shell

以下コマンドでアクセスできます。

mongo -u root \
-p \
--port 27017 \
--host 127.0.0.1
$ mongo -u root \
> -p \
> --port 27017 \
> --host 127.0.0.1
MongoDB shell version v4.2.0
Enter password: 
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") }
MongoDB server version: 4.4.4
WARNING: shell and server versions do not match
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
        http://docs.mongodb.org/
Questions? Try the support group
        http://groups.google.com/group/mongodb-user
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).

The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.

To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

> 

DB操作

一覧確認 ( show dbs )

> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB

DB作成/切り替え( use )

DBを切り替えます。

> use admin;
switched to db admin

存在しないDBを指定するとDBが作成されます。

> use sample_db;
switched to db samle_db
> 
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB
> 
> db.createCollection('user')
{ "ok" : 1 }
> 
> show dbs;
admin      0.000GB
config     0.000GB
local      0.000GB
sample_db  0.000GB

作成しただけだと show dbs で表示されないですが、コレクションも作成すると show dbs で表示されるようになりました。

削除 ( db.dropDatabase() )

> db.dropDatabase();
{ "dropped" : "sample_db", "ok" : 1 }
> 
> show dbs;
admin   0.000GB
config  0.000GB
local   0.000GB

現在のDBを確認 ( db.stats() )

> db.stats()
{
        "db" : "admin",
        "collections" : 2,
        "views" : 0,
        "objects" : 3,
        "avgObjSize" : 208.66666666666666,
        "dataSize" : 626,
        "storageSize" : 65536,
        "indexes" : 3,
        "indexSize" : 98304,
        "totalSize" : 163840,
        "scaleFactor" : 1,
        "fsUsedSize" : 691707797504,
        "fsTotalSize" : 1000240963584,
        "ok" : 1
}

コレクション操作

一覧確認 ( show collections )

> show collections;

作成 ( db.createCollection('xxx') )

> show collections;
> 
> 
> db.createCollection('xxx')
{ "ok" : 1 }
> db.createCollection('yyy')
{ "ok" : 1 }
> 
> show collections;
xxx
yyy

削除 ( db.xxx.drop())

> show collections;
xxx
yyy
> 
> db.xxx.drop()
true
> 
> show collections;
yyy

ドキュメント作成 ( insert )

> use sample_db;
switched to db sample_db
> 
> db.createCollection('user');
{ "ok" : 1 }
> 
> db.user.insert( { id:1, name:'aaa', memo:'aaaaaaaaa', age:21} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:2, name:'bbb', memo:'bbbbbbbbb', age:67} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:3, name:'ccc', memo:'ccccccccc', age:34} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:4, name:'ddd', memo:'ddddddddd', age:22} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:5, name:'eee', memo:'eeeeeeeee', age:62} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:6, name:'fff', memo:'fffffffff', age:33} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:7, name:'aaa', memo:'a2a2a2a2a', age:53} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:8, name:'aaa', memo:'a3a3a3a3a', age:12} );
WriteResult({ "nInserted" : 1 })
> db.user.insert( { id:9, name:'bbb', memo:'b2b2b2b2b', age:52} );
WriteResult({ "nInserted" : 1 })

ドキュメント取得

総数取得 ( count )

> db.user.count();
9

全て取得 ( find )

> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "name" : "ccc", "memo" : "ccccccccc", "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }

指定数取得 ( limit )

> db.user.find().limit(2);
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }

整形表示 ( pretty )

> db.user.find().limit(1).pretty();
{
        "_id" : ObjectId("60627f20f3ae4823415f4505"),
        "id" : 1,
        "name" : "aaa",
        "memo" : "aaaaaaaaa",
        "age" : 21
}

ドキュメント絞り込み
( find({絞り込み条件}) )

> db.user.find({"id":3});
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "name" : "ccc", "memo" : "ccccccccc", "age" : 34 }
> db.user.find({"age":{ $gte: 40 }});
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }

指定フィールドのみ取得
( find({}, {表示フィールド指定}) )

> db.user.find({}, {"id":1, "age":1});
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "age" : 52 }
> db.user.find({}, {"name":0});
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "memo" : "ccccccccc", "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "memo" : "b2b2b2b2b", "age" : 52 }

並び替え ( sort )

> db.user.find({}, {"id":1, "age":1}).sort({"age":1})
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "age" : 12 }
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "age" : 52 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "age" : 67 }
> db.user.find({}, {"id":1, "age":1}).sort({"age":-1})
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "age" : 52 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "age" : 22 }
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "age" : 12 }

ドキュメント更新 ( update )

id=3 であるドキュメントの memoフィールド を更新してみます。

> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "name" : "ccc", "memo" : "ccccccccc", "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }
> 
> db.user.update({"id":3}, {$set:{"memo":"update_xxx"}});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> 
> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "name" : "ccc", "memo" : "update_xxx", "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }

$set を利用しないと以下のように丸ごと更新されるので注意が必要です。

> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "id" : 3, "name" : "ccc", "memo" : "update_xxx", "age" : 34 }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }
> 
> db.user.update({"id":3}, {"memo":"update_xxx"});
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> 
> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "memo" : "update_xxx" }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }

ドキュメント削除 ( remove )

対象ドキュメントを条件指定して削除できます。

> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4506"), "id" : 2, "name" : "bbb", "memo" : "bbbbbbbbb", "age" : 67 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "memo" : "update_xxx" }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }
> 
> db.user.remove({"id":2});
WriteResult({ "nRemoved" : 1 })
> 
> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "memo" : "update_xxx" }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f4509"), "id" : 5, "name" : "eee", "memo" : "eeeeeeeee", "age" : 62 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450b"), "id" : 7, "name" : "aaa", "memo" : "a2a2a2a2a", "age" : 53 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
{ "_id" : ObjectId("60627f26f3ae4823415f450d"), "id" : 9, "name" : "bbb", "memo" : "b2b2b2b2b", "age" : 52 }
> 
> db.user.remove({"age":{$gte:40}});
WriteResult({ "nRemoved" : 3 })
> 
> db.user.find();
{ "_id" : ObjectId("60627f20f3ae4823415f4505"), "id" : 1, "name" : "aaa", "memo" : "aaaaaaaaa", "age" : 21 }
{ "_id" : ObjectId("60627f26f3ae4823415f4507"), "memo" : "update_xxx" }
{ "_id" : ObjectId("60627f26f3ae4823415f4508"), "id" : 4, "name" : "ddd", "memo" : "ddddddddd", "age" : 22 }
{ "_id" : ObjectId("60627f26f3ae4823415f450a"), "id" : 6, "name" : "fff", "memo" : "fffffffff", "age" : 33 }
{ "_id" : ObjectId("60627f26f3ae4823415f450c"), "id" : 8, "name" : "aaa", "memo" : "a3a3a3a3a", "age" : 12 }
> 
> db.user.remove({});
WriteResult({ "nRemoved" : 5 })
> 
> db.user.find();
> 

参考

わくわくBank.
技術系の記事を中心に、役に立つと思ったこと、整理したい情報などを掲載しています。