MongoDBでゆるふわDB体験

第8回リリース間近! MongoDB 2.4の新機能

今回は、リリース間近となっているMongoDB v2.4で追加/改善された機能を紹介します。

v2.4については2月19日に行われた第7回丸の内MongoDB勉強会で取り扱いましたが、今回記事執筆のために改めて確認すると、リリースノートの項目が増えていました。まさにリリースに向けて開発中という雰囲気が伝わってきます。

今回の内容は、3月7日時点のMongoDB v2.4リリースノートを基にしています。

ひとつ前の安定バージョンであるv2.2の新機能については、この連載の以前の記事をお読みください。

新機能ダイジェスト

1. 全文検索機能
ついにインデックス付きの全文検索機能が追加されました!しかし、日本語には対応していませんので注意してください。
2. 権限によるアクセスコントロール
ロールを用いてユーザごとに読み込み権限、書き込み権限をコントロールできるようになりました。
3. JavaScriptエンジンがV8へ
デフォルトのJavaScriptエンジンが、これまでのSpiderMonkeyの拡張版からV8へ変更されました。
4. GeoJSONによる地理空間インデックス
地理空間インデックスを用いてGeoJSONフォーマットのオブジェクトを取り扱うことが可能になりました。
5. ハッシュドシャードキー
シャードキーにハッシュ化したフィールドを指定可能になりました。
6. その他の変更点
他にも細かな変更点があります。後ほど詳細に解説します。

全文検索機能

注意

全文検索は実験的機能という位置づけです。リリースノートで、本番環境での使用を避ける旨が明記されています。

2.4の目玉機能はインデックス付き全文検索です。10genのエンジニアも「ユーザから要望が多かった機能」と説明しています。ただし、執筆時(3月7日)では残念ながら日本語には対応していません。英語・フランス語・ドイツ語など15カ国語が対応言語となっています。最新の対応言語はリリースノートで確認してください。

MongoDBの全文検索は以下のような特徴を持っています。

  • 複数のフィールドを重み付けし、一括検索対象にできるScore Hit方式
  • 検索クエリには正規表現が使用可能
  • ステミングに対応

第7回丸の内MongoDB勉強会には全文検索機能に関してハンズオン資料がありますので併せてご覧ください。

権限によるアクセスコントロール

MySQLなどで権限(PRIVILEGES)を使用していたユーザにはうれしい機能です。MongoDBでも権限によるアクセスコントロールが可能になりました。権限はデータベースごとに設定可能です。{database}.system.usersコレクションに保存します。

roles(権限)内容
readすべてのコレクションのデータを読み取り可能
readWriteすべてのコレクションのデータを読み取りでき、書き込み可能
dbAdminインデックス作成、DBの統計情報取得などのデータベース管理者オペレーションが可能
userAdminsystem.usersに対して読み書きでき、ユーザの作成や権限変更などの管理が可能
clusterAdminレプリカセットやシャーディングの管理者オペレーションが可能
readAnyDatabaseadminデータベースを含めたすべての論理データベースを読み取り可能
readWriteAnyDatabaseadminデータベースを含めたすべての論理データベースを読み取りでき、書き込み可能
userAdminAnyDatabaseuserAdminとしてユーザ管理を行い、すべての論理データベースを読み取りでき、書き込み可能
dbAdminAnyDatabasedbAdminとしてデータベース管理を行い、すべての論理データベースを読み取りでき、書き込み可能

JavaScriptエンジンがV8へ

デフォルトのJavaScriptエンジンがこれまでのSpiderMonkeyの拡張版からV8へ変更され、最新のECMAscript 5thに準拠しました。またV8への変更によって並列処理性能が改善されています。

一方で、これまで使用できていたSpiderMonkeyの独自拡張機能は使用できなくなりました。たとえば、V8では標準でないE4X拡張機能をサポートしていません。これまでにMongoDBでJavaScriptを使用してきたユーザは注意してください。削除された機能の一覧はリリースノートを確認してください。

JavaScriptエンジンはmongo shellからdb.serverBuildInfo()で確認できるようになりました。

> db.serverBuildInfo()

またはinterpreterVersion()でも確認できます。

> interpreterVersion()

GeoJSONによる地理空間インデックス

MongoDBはv1.4から地理空間インデックスをサポートしていますが、今回のバージョンアップでGeoJSONフォーマットを扱えるようになりました。

以下のようなGeoJSONフォーマットでの表記が可能となり、DBへドキュメントとしてinsertできるようになりました。

オブジェクト表記
点(Point)
{ "type": "Point", "coordinates": [ 40, 5 ] }
線(LineString)
{ "type": "LineString", "coordinates": [ [ 40, 5 ], [ 41, 6 ] ] }
多角形(Polygon)
{
  "type": "Polygon",
  "coordinates": [ [ [ 40, 5 ], [ 40, 6 ], [ 41, 6 ], [ 41, 5 ], [ 40, 5 ] ] ]
}

また$geoIntersectsという新しいオペレーターが追加されました。$geoIntersectsを使うと、交差しているオブジェクトを検索することができます。

たとえば、P [ 20, 5 ]という点と交差するGeoJSONオブジェクトを検索できます。図1では点Pと交差している、三角形A、五角形B、直線Lを検索結果として取得できます。五角形C、直線MはPと交差していないため、検索結果に含まれません。

図1 $geoIntersectsで交差しているオブジェクトの検索
図1 $geoIntersectsで交差しているオブジェクトの検索

P [ 20, 5 ]と交差しているオブジェクトの検索は、地理空間インデックス作成後に以下のコマンドで行います。

> db.collection.find( { loc: { $geoIntersects:
                               { $geometry: { "type": "Point",
                                            "coordinates": [ 20, 5 ]
                                } } } } )

今回は地理空間インデックスの作成手順は省略します。第7回丸の内MongoDB勉強会にはGeoJSONを用いたハンズオンが掲載されてます。

ハッシュドシャードキー

シャードキーをハッシュ化することで、データの偏りを防ぐことが可能になりました。

たとえば、シャードキーにメールアドレスを選択した場合を考えてみましょう。みなさんの携帯の電話帳を思い浮かべてみてください。2つのサーバへシャーディングするために、どこかのアルファベットで区切ろうとしても、データに偏り無くわけることは難しいと思います。

図2 ハッシュ化前
図2 ハッシュ化前

ハッシュ化とは、ハッシュ関数を用いて数値や文字列から固定長の値を生成することです。5文字のアルファベットが生成されるハッシュ関数を例に挙げて、説明します。生成される値はランダムなので、AからZまでほぼ同じ数だけ生成されます。

図3 ハッシュ化後
図3 ハッシュ化後

シャードキーであるメールアドレスをハッシュ化することで、データを偏りなく分散させることが可能になりました。

図4 ハッシュ化されたシャードキーでシャーディング
図4 ハッシュ化されたシャードキーでシャーディング

このように、ハッシュドシャードキーを用いることでシャーディングをより簡単に設定できるようになり、データを均等に分散させることが可能になります。

その他の変更点

ケルベロス認証のサポート

WindowsのActive Directoryなどで使用されているケルベロス認証をサポートしました。ただし、サブスクリプト版のみでのサポートです。サブスクリプト版はMongoDBの開発元である10genからサポートを購入することで入手可能となります。

Map-Reduceと$whereオペレーターへ制限の追加

Map-Reduceと$whereオペレーターから、グローバル関数やグローバルプロパティへのアクセスが制限されました。たとえば、mongo shellでよく使用するdbプロパティはグローバルプロパティなので、Map-Reduceと$whereオペレーターからはアクセスできなくなりました。

db.killOp()がインデックス作成に対応

実行中のインデックス作成を、db.killOp()で停止できるようになりました。killOpの引数にはオペレーションIDを取ります。db.currentOp()で取得しましょう。

$setOnInsertオペレーターの追加

$setOnInsertオペレーターを使用することで、upsert時にinsertするドキュメントを指定可能になりました。

_id=1のドキュメントが無い場合、以下のコマンドを実行すると、

> db.collection.update( { _id: 1 },
                        { $setOnInsert: { x: 25, y: 30 } },
                        { upsert: true } )
$setOnInsertで指定した、このようなドキュメントがinsertされます。
{ "_id" : 1, "x" : 25, "y" : 30 }

--setParameterオプションの追加

v2.2まではrunCommandで設定していたパラメーターを、起動時のオプションで指定できるようになりました。v2.2では、以下のコマンドを実行する必要がありました。

> use admin
> db.runCommand( { setParameter: 1, logLevel: 2 } )

v2.4からはmongodの起動時にオプションとして指定できます。

$ mongod --setParameter logLevel=2

確認はrunCommandからgetParameterを行います。

> use admin
> db.runCommand( { getParameter: 1, logLevel: 1 } )
{ "logLevel" : 2, "ok" : 1 }

次回のテーマ

MongoDB v2.4には全文検索、GeoJSON対応、ハッシュドシャードキーなど先進的な機能が追加されました。全文検索に関しましては現状では日本語に対応していませんが、今後が楽しみな機能です。また権限によるアクセスコントロールやケルベロス認証のサポートなど、エンタープライズを意識した機能が追加されたのも特徴的だと思います。MongoDBの開発方針としてエンタープライズを意識しているものと思われます。

次回はMongoDBの機能のひとつである、地理空間インデックスについて紹介する予定です。

おすすめ記事

記事・ニュース一覧