MongoDBの基本概念
これから実際にMongoDBの操作を行っていきますが、その前にMongoDBのデータ構造と用語について簡単に解説しておきます。
ドキュメント
MongoDBにおけるレコードの単位です。RDBMSにおける行に相当し、本記事冒頭で述べた通りBSONという形式で保持されています。
コレクション
複数のドキュメントからなるグループのようなものです。RDBMSにおけるテーブルに相当しますがスキーマというものはありません。
データベース
複数のコレクションを格納します。データベースは複数作成することができます。
MongoDBの基本操作
さて、ここからは先程のシェルを使って実際にMongoDBの操作を行っていきます。基本的な操作を解説するにあたって、実際にデータベースを作成し、次にコレクションを作成します。そして、そのコレクションに対してドキュメントの基本操作(作成、参照、更新、削除)を行っていきます。
データベースの作成
まずはデータベースの作成を行います。MongoDBの場合は、SQLのように明示的にcreateを行う必要はありません。useコマンドを作成したいデータベース名を指定して実行すると、指定した名前のデータベースがその環境に存在しなければ、新たに作られた上でそのデータベースに自動的にスイッチします。すでに同じ名前のデータベースがあれば単にスイッチするだけです。今回は"sample"という名前でデータベースを作成します。
$ ./bin/mongo MongoDB shell version: 2.2.2 connecting to: test 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 > use sample switched to db sample
現在、使用しているデータベースを表示する場合、単に"db"というコマンドを実行します。
> db sample
接続しているサーバ上に存在するデータベースを確認するには、以下のコマンドを実行します。
> show dbs local (empty) sample 0.203125GB
上記ではsampleというデータベースが存在していますが、実際にはこの時点ではsampleというデータベースが表示されていないと思われます。これは中身(=コレクション)のないデータベースは表示されないためです。
コレクションの作成とドキュメントの作成
続いてコレクションの作成を行います。実は、コレクションの作成だけを行う操作は存在しません。MongoDBではドキュメントの作成時にコレクションを指定しますが、このとき、存在しないコレクションが指定されると自動で作成されます。
今回は"sample_coll"という名前のコレクションを作成し、このコレクションに新規にドキュメントを作成します。
> db.sample_coll.insert({ "key1" : "value1", "key2" : "value2" })
何もエラーが表示されていなければ作成は成功しています。
MongoDBで基本的なドキュメントの操作する場合は、操作対象のデータベースとコレクションを指定する必要があります。今回の例で言えば、"db.sample_coll"がそれにあたります。ここで指定している"db"は現在使用しているデータベースを示します。"sample_coll"は例として使うコレクションの名前です。その後のinsert()で指定したコレクションへのドキュメントの作成を行っています。今回は例として"key1"と"key2"というフィールド名で"value1"と"value2"という値をドキュメントのデータとしています。このように、MongoDBではinsert()メソッドの引数として作成するドキュメントのデータをJSON形式で渡す必要があります。
また、ドキュメントは一部の特別なコレクションのドキュメントを除いて、"_id"というフィールドを持っています。この値はコレクション内でユニークである必要があり、通常データタイプとしてBSONのObjectIdが使用されます。しかし、先ほどの例ではこの_idフィールドを指定していません。_idフィールドを指定せずにinsert()メソッドを実行した場合、データベースが自動的にObjectIdを作成し、_idフィールドへと格納します。
なお、この時点で先ほどの"show dbs"を実行すると、今度は中身が存在するためデータベース名が表示されるはずです。また、データベース内に存在するコレクションの一覧を確認するには"show collections"を実行します。
ドキュメントの参照
続いてドキュメントの参照(検索)を行ってみます。MongoDBでは参照用に多種多様なクエリーをサポートしています。例えば、先ほどのコレクションに含まれるすべてのドキュメントを取得する場合は以下のようになります。
> db.sample_coll.find() { "_id" : ObjectId("51068b04b796a688e5d541a9"), "key1" : "value1", "key2" : "value2" }
ドキュメントの検索はfind()メソッドを使用します。find()メソッドを使用する場合もinsert()と同様に、データベースとコレクションを指定する必要があります。また、上記の例では条件を指定せずに実行しているので、指定したコレクションに含まれる全ドキュメントが表示されます。先ほど作成したドキュメントが表示されているかと思いますが、insert()実行時には指定しなかった_idフィールドが自動的に作成されて値が格納されていることが分かります。
次に、複数のドキュメントから条件にマッチしたものを検索する場合は、find()の引数として条件を指定します。条件の指定もJSON形式で行います。もう1件ドキュメントを追加した後、1件だけを条件指定して取得してみます。
> db.sample_coll.insert({ "key3" : "value3", "key4" : "value4" }) > db.sample_coll.find({"key3":"value3"}) { "_id" : ObjectId("510779ccb796a688e5d541aa"), "key3" : "value3", "key4" : "value4" }
MongoDBのドキュメントはスキーマレスであるため、このように異なるフィールド名で同一コレクションにドキュメントを作成することも可能です。上記の例ではフィールド名が"key3"で値が"value3"である、という条件をJSON形式で指定してドキュメントを検索しています。もちろん同一フィールド名のドキュメントがあった場合に、値によって結果を絞り込むことも可能です。
> db.sample_coll.insert({ "key1" : "value1_1", "key2" : "value2_1" }) > db.sample_coll.find() { "_id" : ObjectId("51068b04b796a688e5d541a9"), "key1" : "value1", "key2" : "value2" } { "_id" : ObjectId("510779ccb796a688e5d541aa"), "key3" : "value3", "key4" : "value4" } { "_id" : ObjectId("51077a02b796a688e5d541ab"), "key1" : "value1_1", "key2" : "value2_1" } > db.sample_coll.find({"key1":"value1"}) { "_id" : ObjectId("51068b04b796a688e5d541a9"), "key1" : "value1", "key2" : "value2" }
この例では"key1"という最初に作成したドキュメントと同じフィールドを持つドキュメントを追加していますが、検索条件として"key1"が”value1”であるという条件を指定しているため最初のドキュメントのみが取得されます。
このような基本的なクエリーに加えて、MongoDBではこれ以外にも多種多様な表現を指定可能です。例えば"key1"が"value1"ではないドキュメントを検索する場合は、以下のようになります。
> db.sample_coll.find({"key1": { $ne : "value1" }}) { "_id" : ObjectId("510779ccb796a688e5d541aa"), "key3" : "value3", "key4" : "value4" } { "_id" : ObjectId("51077a02b796a688e5d541ab"), "key1" : "value1_1", "key2" : "value2_1" }
この他にもさまざまな条件の指定の仕方が存在しますので、公式ドキュメントに目を通しておくことを強くおすすめします。
また、find()だけでなくfindOne()というメソッドも存在します。これは検索条件にマッチした最初の1件だけを取得するメソッドになります。取得結果が2件となった先ほどのクエリを今度はfindOne()メソッドを使って実行してみてください。
> db.sample_coll.findOne({"key1": { $ne : "value1" }}) { "_id" : ObjectId("510779ccb796a688e5d541aa"), "key3" : "value3", "key4" : "value4" }
このように検索条件にマッチする1件目のみが取得されました。