##概要
以下観点でまとめたMongoDBの操作系簡易リファレンスです
- とりあえずこれだけ知っていればMongoDBをデータストアとしたアプリ開発に入れる
- 開発Teamメンバーに知っておいてほしいこと
##前提
- MongoDBがセットアップ済みであること
- 参照、更新コマンド、クエリセレクタは最低限使えること
##環境
使用環境 | バージョン |
---|---|
CentOS | 7.6 |
MongoDB server | 4.0.5 |
##状態確認
###データベース一覧
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
###データベース切り替え(新規作成)
> use testdb
switched to db testdb
###コレクション一覧
> show collections
company
department
user
##初期化関連
###コレクションtruncate
> db.user.remove({})
###コレクション削除
> db.user.drop()
###データベース削除
drop対象を指定した状態で実行
> use testdb
> db.dropDatabase()
##設計・パフォーマンスチューニング
###問い合わせプラン確認
> db.user.find({name:"koda"}).explain()
###index確認
> db.user.getIndexes()
###index作成(通常)
value値 1:昇順、-1:降順
> db.user.createIndex({name: 1})
###index作成(ユニーク)
> db.user.createIndex({name: 1}, {unique: true})
###index作成(マルチフィールド)
> db.user.createIndex({name: 1, sex: 1})
##ヘルプ・コマンド確認
###ヘルプ
> help
db.help() help on db methods
db.mycoll.help() help on collection methods
sh.help() sharding helpers
(省略)
###コマンド確認
tab補完が使える
#####DBコマンド
> db.
db.adminCommand( db.fsyncLock( db.getWriteConcern( db.revokePrivilegesFromRole(
db.aggregate( db.fsyncUnlock( db.grantPrivilegesToRole( (省略)
#####コレクションコマンド
> db.user.
db.user.addIdIfNeeded( db.user.getCollection( db.user.mapReduce(
db.user.aggregate( db.user.getDB( db.user.propertyIsEnumerable
(省略)
##コマンドライン実行
###直接実行
$ echo $SHELL
/bin/bash
$ mongo --host localhost --quiet testdb --eval 'db.user.find()'
{ "_id" : ObjectId("5c7768915fd5d6ec50b38477"), "uid" : 1, "name" : "koda", "sex" : "男" }
{ "_id" : ObjectId("5c7768915fd5d6ec50b38478"), "uid" : 2, "name" : "mori", "sex" : "男" }
{ "_id" : ObjectId("5c7768915fd5d6ec50b38479"), "uid" : 3, "name" : "kubo", "sex" : "男" }
###jsを実行
#####jsファイルを準備
var users = db.user.find();
users.forEach(function(user) {
if (user) {
print(user._id + '\t' + user.name + '\t' + user.sex);
}
});
#####実行
$ mongo --quiet testdb ./find.js
5c7768915fd5d6ec50b38477 koda 男
5c7768915fd5d6ec50b38478 mori 男
5c7768915fd5d6ec50b38479 kubo 男
##バックアップ、レストア
###ダンプ
$ mongodump --archive=/tmp/testdb.20190228.gz --gzip --db testdb
###レストア
対象DBがない状態で実行
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
$ mongorestore --gzip --archive=/tmp/testdb.20190228.gz --db testdb
##エクスポート・インポート
###エクスポート
$ mongoexport --db testdb --collection user --out /tmp/user.json
###インポート
$ mongoimport --db testdb_new --collection user --file /tmp/user.json
シーケンス
オートインクリメント用の関数を作成しRDBのシーケンスのように利用する
> use testdb
countersコレクションを作成しておく
> db.counters.insert(
{
_id: "userid",
seq: 0
}
)
> db.counters.find()
{ "_id" : "userid", "seq" : 0 }
オートインクリメント関数を作成
- 永続的に使える状態にするため、db.system.jsに登録しておく
- Mongo shell上で定義した変数やfunctionはログオフで消えてしまうため
> db.system.js.save({_id:'my_seq', value:function (name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
});
確認のためにログオフ
> exit
bye
再接続
$ mongo
> use testdb
登録したスクリプトをロード
> db.loadServerScripts()
シーケンス取得
> my_seq('userid')
1
> my_seq('userid')
2
> my_seq('userid')
3
実際に使う場合はこんな感じ
> db.users.insert({_id: my_seq('userid'), name: "seq_test_user"} )
> db.users.find()
{ "_id" : 4, "name" : "seq_test_user" }
ユーザ認証
スーパーユーザを準備したうえでアプリ用ユーザを作成するイメージ
###ユーザ管理者の登録
#security:
> use admin
> db.createUser({
user:"admin",
pwd:"manager",
roles:[{ role:"userAdminAnyDatabase", db:"admin" }]
})
###再起動
認証設定を有効にする
security:
authorization: enabled
# systemctl restart mongod
###アプリ用ユーザ登録
ユーザ管理者で再接続
$ mongo -u "admin" -p "manager" --authenticationDatabase="admin"
> use testdb
> db.createUser(
{
user: "airuser",
pwd:"airuser",
roles:[
{role:"readWrite", db:"testdb"}
]
}
)
cf. Built-In Roles
###ロール変更
> use testdb
> db.updateUser(
"airuser",
{
roles:[
{role: "readWrite",db: "testdb"}
]
}
)
###登録済みユーザ確認
> use admin
> db.system.users.find()
###接続確認
アプリ用ユーザで接続
$ mongo --host localhost -u "airuser" -p "airuser" --authenticationDatabase="testdb"
許可DBだけ見える
> show dbs
testdb 0.000GB
おまけ
###PHPでアクセス
ユーザ認証ありの状態で検証
#####ファイル準備
<?php
// DBへ接続
$mongo = new MongoClient("mongodb://localhost:27017/testdb",
array("username" => "airuser", "password" => "airuser"));
// データベースを指定
$db = $mongo->selectDB("testdb");
// コレクションを指定
$coll = $db->selectCollection("user");
// コレクションのドキュメントを取得
$docs = $coll->find(array('uid' => 1));
// 表示
foreach ($docs as $id => $obj) {
print_r($obj);
}
?>
#####実行
$ php mongo.php
Array
(
[_id] => MongoId Object
(
[$id] => 5c7787e73cf5a95585ea27f7
)
[uid] => 1
[name] => koda
[sex] => 男
)
###フィールドを縦に展開
利用頻度が高いですよね
> db.user.find().pretty()
{
"_id" : ObjectId("5c7768915fd5d6ec50b38477"),
"uid" : 1,
"name" : "koda",
"sex" : "男"
}
- cf.
- MySQL: SQLの最後に \G
- PostgreSQL: メタコマンド \x
##参考