ドットインストール:MongoDB入門
用語
Database > Collection > Document
DocumentはRDBでいうレコード
スキーマレスなのでキーが異なってもいい
コマンド
ログイン
mongo
help
exit
Database
作成
use DB_NAME:
コレクションを作成しない限り一覧には表示されない
一覧
show dbs
削除
db.dropDatabase()
現在のDBの情報
db.stats()
DBの読み込み
mongoで起動したあとにuse DB_NAMEまたはmongo DB_NAMEで直接起動
Collection
作成
db.createCollection("COLLECTION_NAME")
一覧
show collections
削除
db.NAME.drop()
リネーム
db.OLD_NAME.renameCollection("NEW_NAME")
Document
作成
code:zsh
db.members.insert(
... {name: "gaku",
... age:17}
... );
collectionがなくてもこのようにinsertすれば自動的に生成される
同じkey-valueの組み合わせのデータも別物(idが別)として扱われる
一覧
db.COLLECTION_NAME.find()
削除
db.COLLECTION_NAME.remove({}) // 全件削除
Collectionに含まれるドキュメントの数
db.COLLECTION_NAME.count()
JavaScriptの構文が使える
ユニークなidが自動で振られる
find()をほりさげる
準備
てきとーなデータセット(適当すぎて適切ではないし内容も間違ってる…)
code:zsh
db.members.find()
{ "_id" : ObjectId("5b3ba2c8fc7416f3f09981e8"), "name" : "gaku", "age" : 17 }
{ "_id" : ObjectId("5b3ba6af7182e81d5187fb8f"), "name" : "ago", "age" : 17 }
{ "_id" : ObjectId("5b3ba6b37182e81d5187fb90"), "name" : "iincho", "age" : 17 }
{ "_id" : ObjectId("5b3ba6b77182e81d5187fb91"), "name" : "dero", "age" : 17 }
{ "_id" : ObjectId("5b3ba6bb7182e81d5187fb92"), "name" : "dero", "age" : 18 }
{ "_id" : ObjectId("5b3ba6c47182e81d5187fb93"), "name" : "dero", "age" : 18 }
特定のKey-valueに一致するものだけ表示
code:zsh
db.members.find({age: 18})
{ "_id" : ObjectId("5b3ba6bb7182e81d5187fb92"), "name" : "dero", "age" : 18 }
{ "_id" : ObjectId("5b3ba6c47182e81d5187fb93"), "name" : "dero", "age" : 18 }
比較
code:zsh
db.members.find({age: {$gte: 18}})
{ "_id" : ObjectId("5b3ba6bb7182e81d5187fb92"), "name" : "dero", "age" : 18 }
{ "_id" : ObjectId("5b3ba6c47182e81d5187fb93"), "name" : "dero", "age" : 18 }
以上gteや以下lte、等しいeq、等しくないneを使える
JavaScriptの正規表現を利用することもできる 名前にgoを含む
code:zsh
db.members.find({name: /go/})
{ "_id" : ObjectId("5b3ba6af7182e81d5187fb8f"), "name" : "ago", "age" : 17 }
キー名の抽出
nameの一覧が見たい
code:zsh
db.members.distinct("name")
AND検索
code:zsh
db.members.find({name: /dero/, age: 17})
{ "_id" : ObjectId("5b3ba6b77182e81d5187fb91"), "name" : "dero", "age" : 17 }
OR検索
code:zsh
{ "_id" : ObjectId("5b3ba6af7182e81d5187fb8f"), "name" : "ago", "age" : 17 }
{ "_id" : ObjectId("5b3ba6b37182e81d5187fb90"), "name" : "iincho", "age" : 17 }
キーの中の複数の特定の値
code:zsh
{ "_id" : ObjectId("5b3ba2c8fc7416f3f09981e8"), "name" : "gaku", "age" : 17 }
{ "_id" : ObjectId("5b3ba6af7182e81d5187fb8f"), "name" : "ago", "age" : 17 }
要素の有無
code:zsh
# 要素追加
db.members.insert({"name":"eru", "age":240, "ikiri":true})
# ikiriが存在してるドキュメントだけ抽出
db.members.find({ikiri:{$exists:true}})
{ "_id" : ObjectId("5b3bb0af7182e81d5187fb94"), "name" : "eru", "age" : 240, "ikiri" : true }
フィールドの表示
第二引数で表示したいフィールドを指定できる
code:zsh
db.members.find({}, {name:true})
{ "_id" : ObjectId("5b3ba2c8fc7416f3f09981e8"), "name" : "gaku" }
{ "_id" : ObjectId("5b3ba6af7182e81d5187fb8f"), "name" : "ago" }
{ "_id" : ObjectId("5b3ba6b37182e81d5187fb90"), "name" : "iincho" }
{ "_id" : ObjectId("5b3ba6b77182e81d5187fb91"), "name" : "dero" }
{ "_id" : ObjectId("5b3ba6bb7182e81d5187fb92"), "name" : "dero" }
{ "_id" : ObjectId("5b3ba6c47182e81d5187fb93"), "name" : "dero" }
{ "_id" : ObjectId("5b3bb0af7182e81d5187fb94"), "name" : "eru" }
{name:0}にすると名前以外が表示される
0と1は混在できない
code:zsh
db.members.find({}, {name:0, age:1})
Error: error: {
"ok" : 0,
"errmsg" : "Projection cannot have a mix of inclusion and exclusion.",
"code" : 2,
"codeName" : "BadValue"
}
ただし_idは他のフィールドが1でも0にできる
ソート
年齢でソートする
code:zsh
db.members.find({}, {_id: 0}).sort({age: 1})
{ "name" : "gaku", "age" : 17 }
{ "name" : "ago", "age" : 17 }
{ "name" : "iincho", "age" : 17 }
{ "name" : "dero", "age" : 17 }
{ "name" : "dero", "age" : 18 }
{ "name" : "dero", "age" : 18 }
{ "name" : "eru", "age" : 240, "ikiri" : true }
1は昇順。0は降順
skipで前半を飛ばす
code:zsh
db.members.find({}, {_id: 0}).sort({age: 1}).skip(5)
{ "name" : "dero", "age" : 18 }
{ "name" : "eru", "age" : 240, "ikiri" : true }
limit
code:zsh
db.members.find({}, {_id: 0}).sort({age: 1}).limit(1)
{ "name" : "gaku", "age" : 17 }
limit(1)はfindOneと同じ
ソート順は?kadoyau.icon
code:zsh
db.members.findOne({}, {_id: 0})
{ "name" : "gaku", "age" : 17 }
ドキュメントの更新
複数のフィールドを更新するupdate()
code:zsh
db.members.update({name: "ago"}, {$set: {"age":27, "song":"sharpnes..."}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
db.members.find({name: "ago"})
{ "_id" : ObjectId("5b3ba6af7182e81d5187fb8f"), "name" : "ago", "age" : 27, "song" : "sharpnes..." }
💣$setを書き忘れると全体が更新される
code:zsh
db.members.update({name: "ago"}, {"name": "rikiya"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
db.members.find({name: "ago"}) # そんなレコードはもうない
db.members.find({name: "rikiya"})
{ "_id" : ObjectId("5b3ba6af7182e81d5187fb8f"), "name" : "rikiya" }
💣抽出条件に合致するものは1つのレコードしか更新されない
code:zsh
db.members.update({name: "dero"}, {$set: {"age":27}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
db.members.find({name: "dero"})
{ "_id" : ObjectId("5b3ba6b77182e81d5187fb91"), "name" : "dero", "age" : 27 }
{ "_id" : ObjectId("5b3ba6bb7182e81d5187fb92"), "name" : "dero", "age" : 18 }
{ "_id" : ObjectId("5b3ba6c47182e81d5187fb93"), "name" : "dero", "age" : 18 }
第三引数に{multi: true}を指定するとすべてが更新される
code:zsh
db.members.update({name: "dero"}, {$set: {"age":27}}, {multi:true})
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 2 })
db.members.find({name: "dero"})
{ "_id" : ObjectId("5b3ba6b77182e81d5187fb91"), "name" : "dero", "age" : 27 }
{ "_id" : ObjectId("5b3ba6bb7182e81d5187fb92"), "name" : "dero", "age" : 27 }
{ "_id" : ObjectId("5b3ba6c47182e81d5187fb93"), "name" : "dero", "age" : 27 }
現在の値をもとに更新する(インクリメントとか)
使い方は↑と同じ
$inc インクリメント
$mul 掛け算
$rename フィールド名の変更
$set/$unset フィールドの追加/削除
情報があったらupdate、なかったら追加
$upsert
update or insert。条件に一致するものがあればupdate、なければinsert
通常のupdateは条件に一致するものがなければ何も行われない
code:zsh
# 普通にupdateしてもマッチしなければ何も起きない
db.members.update({"name":"kazaki"}, {"name":"kazaki", "age": 9})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
# upsertをつけると作成される
db.members.update({"name":"kazaki"}, {"name":"kazaki", "age": 9}, {upsert: true})
WriteResult({
"nMatched" : 0,
"nUpserted" : 1,
"nModified" : 0,
"_id" : ObjectId("5b3bc91a6eea69d87b7a82a3")
})
db.members.find({"name":"kazaki"})
{ "_id" : ObjectId("5b3bc91a6eea69d87b7a82a3"), "name" : "kazaki", "age" : 9 }
# マッチしたら更新される
db.members.update({"name":"kazaki"}, {"name":"kazaki", "age": 99}, {upsert: true})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
db.members.find({"name":"kazaki"})
{ "_id" : ObjectId("5b3bc91a6eea69d87b7a82a3"), "name" : "kazaki", "age" : 99 }
Indexをフィールドにはる
いまはられてるのは?
code:zsh
db.members.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "nijisanji.members"
}
]
idのindexを消すことはできない
indexの作成
降順 -1, 昇順 1
code:zsh
db.members.createIndex({age: -1});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
db.members.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "nijisanji.members"
},
{
"v" : 2,
"key" : {
"age" : -1
},
"name" : "age_-1",
"ns" : "nijisanji.members"
}
]
削除
nameを渡す
code:zsh
db.members.dropIndex("age_-1")
{ "nIndexesWas" : 2, "ok" : 1 }
uniqueキーを付ける
code:zsh
# すでに重複してるからuniqueをつけることができない
db.members.createIndex({name: 1}, {unique: true})
{
"ok" : 0,
"errmsg" : "E11000 duplicate key error collection: nijisanji.members index: name_1 dup key: { : \"dero\" }",
"code" : 11000,
"codeName" : "DuplicateKey"
}
重複を消して↑を実行すれば重複した名前をinsertしようとしたときにエラーになる
aggregateを使って削除する
バックアップと復元
mongodump -d DB_NAMEで/dump以下にdumpされる
mongorestoreでリストアされる。デフォルトでdumpディレクトリを見てくれる
詳しく知りたい場合には--helpをつける
code:zsh
# --dropをつけないと重複したドキュメントの更新に失敗する(重複していないものはリストアされる)
$ mongorestore
2018-07-03T19:31:44.593+0000 using default 'dump' directory
2018-07-03T19:31:44.594+0000 preparing collections to restore from
2018-07-03T19:31:44.605+0000 reading metadata for nijisanji.members from dump/nijisanji/members.metadata.json
2018-07-03T19:31:44.606+0000 restoring nijisanji.members from dump/nijisanji/members.bson
2018-07-03T19:31:44.618+0000 error: multiple errors in bulk operation:
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3ba2c8fc7416f3f09981e8') }
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3ba6af7182e81d5187fb8f') }
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3ba6b37182e81d5187fb90') }
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3ba6b77182e81d5187fb91') }
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3ba6bb7182e81d5187fb92') }
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3ba6c47182e81d5187fb93') }
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3bb0af7182e81d5187fb94') }
- E11000 duplicate key error collection: nijisanji.members index: _id_ dup key: { : ObjectId('5b3bc91a6eea69d87b7a82a3') }
2018-07-03T19:31:44.618+0000 no indexes to restore
2018-07-03T19:31:44.618+0000 finished restoring nijisanji.members (8 documents)
2018-07-03T19:31:44.619+0000 done
# dropをつける
$ mongorestore --drop
2018-07-03T19:32:39.318+0000 using default 'dump' directory
2018-07-03T19:32:39.318+0000 preparing collections to restore from
2018-07-03T19:32:39.331+0000 reading metadata for nijisanji.members from dump/nijisanji/members.metadata.json
2018-07-03T19:32:39.359+0000 restoring nijisanji.members from dump/nijisanji/members.bson
2018-07-03T19:32:39.374+0000 no indexes to restore
2018-07-03T19:32:39.376+0000 finished restoring nijisanji.members (8 documents)
2018-07-03T19:32:39.378+0000 done