MongoDBでゆるふわDB体験

第3回 MongoDBのクエリを使いこなそう

この記事を読むのに必要な時間:およそ 6 分

はじめに

本記事では,MongoDBのクエリを解説します。MongoDBはリレーショナルデータベース(以下"RDB"と略記)ではないため,SQLは使用できません。その代わり,MongoDB特有の「Mongoクエリ言語」を用います。Mongoクエリ言語のCRUD操作については公式ドキュメントに詳しい解説があります。

本記事の構成は,最初にMongoクエリ言語の特徴について解説し,2ページ目ではSQLとMongoクエリ言語の比較を行います。3ページ目では,MongoDBクエリ言語の使い方を説明し,最後に,プログラミング言語からの利用の仕方の説明として,Rubyからの利用を説明します。

Mongoクエリ言語の特徴

Mongoクエリ言語には以下の特徴があります。

  • コレクションの各メソッドを用いてCRUD操作をします
  • メソッドの引数にはJSON形式のデータを渡します
  • 変数が使えます
  • 制御構造が使えます
  • カーソルが使えます
  • ドキュメントの要素に簡単にアクセスができます

Mongoクエリ言語はMongoDBのコマンドラインインターフェースであるMongoDBシェルから使用できます。シェルは以下のコマンドから起動します。

$ mongo
MongoDB shell version: 2.2.1
connecting to: test
>

コレクションの各メソッドを用いてCRUD操作をします

たとえば,データを挿入する場合は,コレクション「col1」のメソッドinsertを呼び出します。

> db.col1.insert( { "name" : "mongo" } )

更新,参照,削除といったデータ操作も,すべてコレクションのメソッドを用います。

メソッドの引数にはJSON形式のデータを渡します

データを挿入する場合には,insertの引数にJSONのデータを渡します。

> db.col1.insert( { "string" : "hello" , "array" : [ "sun", "mon", "tue" ] } )

参照する場合は,絞込みの条件をJSON形式で指定します。以下の例では,キー"name"の値が正規表現"/mongo/"に一致するものを検索しています。

> db.col1.find( { "name" => /mongo/ } )

変数が使えます

MongoDBのシェルではJavaScriptの文法で,変数が使えます。そのため,挿入するデータや検索条件をあらかじめ変数で定義しておき,メソッドに渡すことができます。

> data = { "string" : "hello" , "array" : [ "sun", "mon", "tue" ] }
> db.col1.insert( data )

> condition = { "name" => /mongo/ }
> db.col1.find( condition )

制御構造が使えます

MongoDBのシェルではJavaScriptの制御構造が使えます。たとえば,以下のようにforループでデータを挿入できます。

> for (var i = 1; i <= 20; i++) db.col1.insert( { x : 4 , j : i } )

カーソルが使えます

検索結果に対するカーソルを定義して,while等の制御構造でアクセスできます。

> var c = db.col1.find()
> while ( c.hasNext() ) printjson( c.next() )

ドキュメントの要素に簡単にアクセスができます

たとえば以下のようなドキュメントを挿入したとします。

> db.col1.insert( { "key1" : "hello" , "array1" : [ "sun", "mon", "tue" ] } )

すると,そのドキュメントに対して,JavaScriptの文法を用いて,以下のように簡単にアクセスできます。

> doc=db.col1.findOne()  // <- ドキュメントを変数に格納
> printjson(doc["key1"]) // <- キー"key1"の値を表示
"hello"
> printjson(doc["array1"][2]) // <- キーarrayの配列の2番目の要素を表示
"tue"

MongoDBのデータ構造

MongoDBでは,データベースごとに複数のコレクションを持ち,コレクションごとに複数のドキュメントを持ちます。ドキュメントはJSON形式で,以下のような構造をしています。

図1 ドキュメントの例

図1 ドキュメントの例

RDBとMondoDBのデータ構造の比較

MongoDBのデータ構造とRDBのデータ構造の比較を以下の表に記載します。

RDBでの呼称MongoDBでの呼称
databasedatabase
tablecollection
rowdocument
columnfield
indexindex
primary key_id field

※ MongoDBでは,"_id"の値に自動的に一意な文字列が採番されます。

RDBとMongoDBの大きな違いは,RDBではテーブル中のすべてのレコードが同じカラムを有するのに対し,MongoDBではドキュメントごとに自由なフィールドを定義できる点です。

しかし,それ以外のデータ構造は,呼称は異なるものの,RDBとMongoDBで対応するものが存在します。すなわち,RDBにおいて,データベースが複数のテーブルを持ち,テーブルが複数のレコードを持ち,レコードがカラムにより区切られているように,MongoDBにおいても似たような構造を持つことができるのです。

この特徴を生かして,次のページでは,慣れ親しんだSQLとMongoクエリ言語の比較していくことで, Mongoクエリ言語への理解を深めていきましょう。

著者プロフィール

藤崎祥見(ふじさきしょうけん)

野村総合研究所 OpenStandia所属。オープンソースのR&Dとセミナー講師を担当。

Debian,Ubuntu,Liferayのコミュニティで活動した後,MongoDBの翻訳に関わり,丸の内MongoDB勉強会を始める。

実家がお寺で,住職の資格を所持する坊主系エンジニア。

Twitter:@syokenz


渡部徹太郎(わたなべてつたろう)

野村総合研究所 OpenStandia所属。オープンソースを使ったSIやサポートの業務に従事。

藤崎と共同で丸の内MongoDB勉強会を始める。

趣味は自宅サーバ。好きなものはLinuxとRuby。

Twitter:@fetarodc


林田敦(はやしだあつし)

野村総合研究所 OpenStandia所属。オープンソースを使ったSIや製品開発業務に従事。

丸の内MongoDB勉強会では広報兼雑用係を務める。

趣味はレザークラフト,ダイビング,スキー,キャンプ,ジェットスキー,カメラ等々。作って滑って撮って潜れるエンジニア。

Facebook:Atsushi Hayashida

コメント

  • 正規表現による絞り込み検索について

    正規表現によるドキュメントの絞り込み検索のコマンド書式として、 db.col1.find( { "name" => /mongo/ } ) のような例が掲載されていますが、正しくは db.col1.find( { "name" : /mongo/ } ) となるべきではないでしょうか。

    http://docs.mongodb.org/manual/reference/operator/query/regex/#op._S_regex

    Commented : #1  Kensuke Nagae (2013/10/28, 15:48)

コメントの記入