「第1回 使ってみようMongoDB」で紹介したように,MongoDBは"RDBライクなクエリ"を実行可能です。 今回は,RDBと比較しながら,MongoDBのクエリについて学びたいと思います。
MongoDBのクエリを解説する前に,まずはRDBとの用語の違いを明確にしておきます。
RDBでの呼称 | MongoDBでの呼称 |
---|---|
database | database |
table | collection |
raw(レコード) | document |
column | field |
index | index |
primary key | _id field |
ここで重要なことは,呼称は異なるものの,RDBにおける概念がほぼそのままMongoDBにも適用できるということです。
すなわち,RDBにおいて,データベースが複数のテーブルを持ち,テーブルが複数のレコードを持ち,
レコードがカラムにより区切られているように,MongoDBにおいても,データベースが複数のコレクションを持ち,
コレクションが複数のドキュメントを持ち,ドキュメントがフィールドにより区切られているのです。
これが,MongoDBで"RDBライクなクエリ"を実行できる理由です。
大きな違いは,RDBではテーブル中の全てのレコードが同じカラムを有するのに対し,
MongoDBではドキュメントごとに独自のフィールドを有することができる点です。
"第1回 使ってみようMongoDB"で解説したように,
MongoDBでは,JavaScriptとJSON形式のハッシュデータを使ってデータを操作します。
ここでは,MongoDBで使用するクエリを,慣れ親しんだMySQLのクエリと比較しながら学んでみましょう。
MySQL | MongoDB |
---|---|
show databases; | show dbs |
データベースを選択する
- MySQL
> use [データベース名]
- MongoDB
> use [データベース名]
データベースを作成する
- MySQL
create database [データベース名]
- MongoDB
なし
MongoDBのデータベースは,データベースを選択し,コレクションへ最初のドキュメントを insertしたタイミングで作成されます。
データベースを削除する
- MySQL
> drop database [データベース名]
- MongoDB
> db.dropDatabase()
MongoDBでは,useコマンドでデータベースを選択しておく必要があります。
MongoDBのコレクションは,MySQLのテーブルに該当します。
コレクションを作成する
- MySQL
> create table [テーブル名] ([スキーマ定義]);
- MongoDB
不要
MongoDBのコレクションは,コレクションへ最初のドキュメントをinsertしたタイミングで作成されます。
明示的にコレクションを作成したい場合,以下のようにすることもできます。
もちろん,MySQLと違ってスキーマ定義は行いません。
- MongoDB
db.createCollection("[コレクション名]")
コレクションを参照する
- MySQL
> show tables;
- MongoDB
> show collections
コレクションを削除する
- MySQL
> drop table [テーブル名];
- MongoDB
> db.[コレクション名].drop()
コレクション内のデータを全て削除する
- MySQL
> truncate table [テーブル名];
- MongoDB
> db.[コレクション名].remove()
MongoDBのドキュメントは,MySQLのレコードに該当します。
- MySQL
> insert into [テーブル名] values([レコードの内容]);
- MongoDB
> db.[コレクション名].insert([ドキュメントの内容])
MongoDBでは,JavaScriptをクエリに使用します。 したがって,以下のようにfor文を使ってドキュメントをinsertすることも可能です。
- MongoDB - JavaScriptを使用した例
> for(var i=1; i<=20; i++) db.testcoll.insert({"stock":i})
まずは,コレクションの中の,全ドキュメントの全フィールドを取得してみます。 MySQLでいうと,テーブルの中の,全レコードの全カラムを取得することと同じです。
- MySQL
> select * from [テーブル名];
- MongoDB
> db.[コレクション名].find()
MongoDBでは,クエリを実行した結果,標準で20件以上のドキュメントが返された場合, 19件目を表示した次の行に"has more"と表示されます。 続きのドキュメントを表示したい場合は,以下のようにします。
- MongoDB
> it
itは"イテレータ"を意味するコマンドで,次の19件を表示することができます。
一度に全てのドキュメントを表示したい場合は,以下のようにします。
- MongoDB
> db.marunouchi.find().toArray() または > db.marunouchi.find().toArray().forEach(printjsononeline)
なお,一度に表示できるドキュメントの数を変更したい場合は,次のようにします。
- MongoDB
> DBQuery.shellBatchSize = [一度に表示したいドキュメント数]
件数を指定して取得するには,以下のようにします。
まずは,1件だけ表示したい場合です。
- MySQL
> select * from [テーブル名] limit 1;
- MongoDB
> db.[コレクション名].findOne()
次に,n件表示したい場合です。
- MySQL
> select * from [テーブル名] limit [n];
- MongoDB
> db.[コレクション名].limit([n])
次に,コレクションの中のドキュメント数をカウントしてみます。
- MySQL
> select count(*) from [テーブル名];
- MongoDB
> db.[コレクション名].count()
今度は,取得するフィールドを指定してみましょう。 コレクションの中の,全ドキュメントの特定のフィールドだけを表示してみます。
- MySQL
> select [カラム名1],[カラム名2],...,[カラム名n] from [テーブル名];
- MongoDB
> db.[コレクション名].find({},{"[フィールド名1]":1,"[フィールド名2]":1,...,"[フィールド名n]":1})
この場合,_idフィールドは常に表示されます。 _idフィールドを含め,特定のフィールドを非表示にしたい場合は,以下のようにします。
- MongoDB
> db.[コレクション名].find({},{"[フィールド名1]":0,"[フィールド名2]":0,...,"[フィールド名n]":0})
これらの表示/非表示は,クエリに混在させることができます。
- MongoDB - フィールドの表示/非表示が混在した例
> db.testcoll.find({},{"_id":0,"key1":1,"key2":0})
- mysql> select _id from where stock = 10
> db.marunouchi.find({"stock":10}, {"_id":1})
- mysql> select _id from where stock {>, <, >=, <=} 10
> db.marunouchi.find({ "stock": { $gt: 10 } }, { "_id": 1 }) > db.marunouchi.find({ "stock": { $lt: 10 } }, { "_id": 1 }) > db.marunouchi.find({ "stock": { $gte: 10 } }, { "_id": 1 }) > db.marunouchi.find({ "stock": { $lte: 10 } }, { "_id": 1 })
- JSON形式で表示
> db.marunouchi.find().forEach(printjson) > db.marunouchi.find().forEach(printjsononeline)
- toArray
> db.marunouchi.find().toArray()
- mysql> update marunouchi set version = 7 where name = 'debian'
> db.marunouchi.update({"name":"debian"},{$set:{"version":7}}) //$setがないと他のフィールドが消えてしまうので注意
- _idが存在すればupdate、存在しなければinsert
> db.marunouchi.save({"_id":ObjectId("xxxx"),"version":7})
- mysql> delete from marunouchi where name = 'centos'
> db.marunouchi.remove({"name":"centos"})
- INDEX参照
> db.system.indexes.find()
- INDEX作成
> db.marunouchi.ensureIndex({"stock":1})
- INDEX削除
> db.marunouchi.dropIndex({"stock":1}) > db.marunouchi.dropIndexes() //全て削除
descコマンドはありません // mysql> desc {table_name}
- ハッシュであるdbのキー一覧を表示してみる
> for(var k in db) print(k) > //versionというキーあり、呼んでみる > db.version > db.version()