MongoDBの基本操作(その1)

ターミナルから直接MongoDBを操作するときのメモ

DB起動

MongoDBのデーモンプロセスは、mongodコマンドを使って起動する。
幾つかオプションはあるが、基本はルートディレクトリを指定するだけで動作する。DBデータが存在しないディレクトリを指定してmongodを起動すると、初回起動とみなして指定したディレクトリにDBデータを展開する。

> mongod --dbpath=[database root directory]

コンソール起動

mongodが起動した状態で、ターミナルからmongoを実行すると、コンソール入力状態になる。

xxx > mongo
MongoDB shell version: 3.0.5
connecting to: test
>

DBの選択、コレクション一覧

コンソールを起動すると、デフォルトではtestデータベースがアクティブ状態になる。これから作成したい又は使用したデータベースをuseコマンドで選択する。存在しないデータベースを選択すると、insertコマンド実行時にデータベースとコレクションが自動生成されるので注意する。show collectionsコマンドは、アクティブデータベース内のコレクションが一覧表示される。

> show dbs
local    0.078GB
> use local
switched to db local
> show collections
startup_log
system.indexes

データの追加

insertコマンドで追加する。引数にJson形式で「フィールド名:値」を指定する。スキーマレスなので、同一コレクションに異なるデータ構造を追加できる。フィールド値にJsonデータを追加して、embedなネスト状態にもできる。
以下の例では、testデータベースのpersonsコレクションに幾つかのドキュメントを追加している。初回のinsertで、testデータベースとpersonsコレクションが作成される。

> use test
switched to db test
> db.persons.insert({
  "name":"taro",
  "gender":"m",
  "age":20,
  "children":["ichiro", "jiro", "saburo"],
  "job":{"name":"AAA co.","category":"salesman"}
})
WriteResult({ "nInserted" : 1 })
 
>db.persons.insert({
  "name":"ken",
  "gender":"m",
  "age":30,
  "job":{"name":"AAA co.","category":"engineer"}
})
WriteResult({ "nInserted" : 1 })
 
>db.persons.insert({
  "name":"hanako",
  "gender":"f",
  "age":32,
  "children":["yumi"],
  "job":{"name":"BBB co.","category":"operator"}
})
WriteResult({ "nInserted" : 1 })

テンプレート

db.persons.insert({"name" : "taro", "gender" : "m", "age" : 20, "children" : [ "ichiro", "jiro", "saburo" ], "job" : { "name" : "AAA co.", "category" : "salesman" } })
db.persons.insert({"name" : "ken", "gender" : "m", "age" : 30, "job" : { "name" : "AAA co.", "category" : "engineer" } })
db.persons.insert({"name" : "hanako", "gender" : "f", "age" : 32, "children" : [ "yumi" ], "job" : { "name" : "BBB co.", "category" : "operator" } })

とりあえず、男子2人、女子1人を追加、それぞれ年齢、職業、子供の有無が異なるデータである。
childrenが配列データ、jobがオブジェクト型になっている。プログラマ寄りの直感的なデータ構造のままデータ保持できる。_idは、自動的に生成されるドキュメントのユニークIDで、RDBMSのprimary keyに相当する。

データの参照

RDBMSのSELECT文に相当するfindコマンドでコレクション内のドキュメントを参照する。引数にJson形式で条件を追加して絞り込むことももちろん可能(Where句)。先に登録したpersonsコレクションに対し検索してみる。

  • 条件なし(全件検索)
> db.persons.find()
{ "_id" : ObjectId("55cec1e62aae174a23628568"), "name" : "taro", "gender" : "m", "age" : 20, "children" : [ "ichiro", "jiro", "saburo" ], "job" : { "name" : "AAA co.", "category" : "salesman" } }
{ "_id" : ObjectId("55cec57e2aae174a23628569"), "name" : "ken", "gender" : "m", "age" : 30, "job" : { "name" : "AAA co.", "category" : "engineer" } }
{ "_id" : ObjectId("55cec5ca2aae174a2362856a"), "name" : "hanako", "gender" : "f", "age" : 32, "children" : [ "yumi" ], "job" : { "name" : "BBB co.", "category" : "operator" } }

  • nameがkenのドキュメント
> db.persons.find({"name":"ken"})
{ "_id" : ObjectId("55cec57e2aae174a23628569"), "name" : "ken", "gender" : "m", "age" : 30, "job" : { "name" : "AAA co.", "category" : "engineer" } }
  • embedなフィールドjob.categoryで検索
>db.persons.find({"job.category":"operator"})
{ "_id" : ObjectId("55cec5ca2aae174a2362856a"), "name" : "hanako", "gender" : "f", "age" : 32, "children" : [ "yumi" ], "job" : { "name" : "BBB co.", "category" : "operator" } }

  • ageが20以上、30未満 (以上:$gte、以下:$lte、より大きい:$gt、未満:$lt)
> db.persons.find({"age":{$gte:20,$lte:30}})
{ "_id" : ObjectId("55cec1e62aae174a23628568"), "name" : "taro", "gender" : "m", "age" : 20, "children" : [ "ichiro", "jiro", "saburo" ], "job" : { "name" : "AAA co.", "category" : "salesman" } }
{ "_id" : ObjectId("55cec57e2aae174a23628569"), "name" : "ken", "gender" : "m", "age" : 30, "job" : { "name" : "AAA co.", "category" : "engineer" } }
  • OR検索 $or (AND検索は$and)
db.persons.find({ $or:[{"name":"taro"},{"gender":"f"}] })
{ "_id" : ObjectId("55cec1e62aae174a23628568"), "name" : "taro", "gender" : "m", "age" : 20, "children" : [ "ichiro", "jiro", "saburo" ], "job" : { "name" : "AAA co.", "category" : "salesman" } }
{ "_id" : ObjectId("55cec5ca2aae174a2362856a"), "name" : "hanako", "gender" : "f", "age" : 32, "children" : [ "yumi" ], "job" : { "name" : "BBB co.", "category" : "operator" } }

ほかにもたくさんあって書ききれないが、RDBMSでよく使うクエリ条件はほとんどある。

重複を除外して、該当フィールド値だけを返す(distinct())

> db.persons.distinct("name")
[ "taro", "ken", "hanako" ]
 
> db.persons.distinct("job.name")
[ "AAA co.", "BBB co." ]

ドキュメントの削除 (remove())

removeコマンドを使う、引数にJson形式で条件を追加できる。SQLの”Delete From テーブル名”に相当する。

  • 名前がtaroのドキュメントを削除
> db.persons.remove({"name":"taro"})
WriteResult({ "nRemoved" : 1 })
> db.persons.find()
{ "_id" : ObjectId("55ced7c22aae174a2362856c"), "name" : "ken", "gender" : "m", "age" : 30, "job" : { "name" : "AAA co.", "category" : "engineer" } }
{ "_id" : ObjectId("55ced7c22aae174a2362856d"), "name" : "hanako", "gender" : "f", "age" : 32, "children" : [ "yumi" ], "job" : { "name" : "BBB co.", "category" : "operator" } }
  • 全削除 (remove())
> db.persons.remove({})
WriteResult({ "nRemoved" : 3 })
> db.persons.find()
> 

コレクションを削除 (drop())

dropコマンドをつかう。SQLの”Drop Table テーブル名”に相当する。

> db.persons.drop()
true
> show collections
system.indexes

データベースの削除 (db.dropDatabase())

db.dropDatabaseでカレントのデータベースが削除される。SQLの”Drop Database データベース名”に相当する。

> use test
switched to db test
> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }
>
> show dbs
local    0.078GB

コレクション名の変更 (renameCollection())

renameCollectionでリネームできる

> show collections
persons
system.indexes
> db.persons.renameCollection("people")
{ "ok" : 1 }
> show collections
people
system.indexes