MongoDB で インデックス を 適用する 方法

0 件のコメント

今回は 「MongodB における インデックス の取り扱い」 についてよく使いそうなものを中心にまとめます。

MongoDB がドキュメント型データベースであるが故、ちょっと変わったインデックスが存在します。 今回はそれら RDB にないインデックスの概念も取り上げます。

MongoDB における インデックス

MongoDB では デフォルトで _id プロパティ が一意なインデックスとしてドキュメントを作成するたびに自動的に作成されます。 これで足りない場合は独自で db.collection.createIndex() を使ってインデックス作成します。 db.collection.createIndex() を用いて作られるインデックスは B-tree データ構造のインデックスです。

MongoDBでは単純なキー指定以外にもいくつかのインデックス種別をサポートしています。 具体的にサポートしているインデックス種別は以下の通りです。

  • 単一キー
  • 複合キー
  • マルチキー
  • 地理
  • テキスト
  • ハッシュ

「複合キー」と「マルチキー」は名称が似ていますが中身は異なります。 「複合キー」は「複数フィールドを組み合わせたキー」で、「マルチキー」は「配列を取るプロパティに対してその配列に含まれる値すべて対象とするキー」とするものです。

以下では基本となる「単一キーインデックス」「複合キーインデックス」「マルチキーインデックス」についてその具体的な使い方をサンプルコードを用いて見ていきます。

インデックス作成 の 基本

mongoシェル上で以下のコマンドを実行することで、指定されたコレクションに対してインデックスを作成することができます。

JavaScriptコード上でも関数は同じですが、第3引数にコールバックが指定できるようになる点が異なります。

構文

db.collection.createIndex(keys, options)

引数

keys

Type: string / object

値を持つフィールド名を指定します。 昇順のキーであれば 1 を、降順のキーであれば -1 を指定します。

options

Type: object

インデックス作成に関するオプションを指定します。 オプション指定できるものには以下のようなものがあります(ほかにもありますがここではピックアップ)。

  • unique
  • collation

使用例

以下で「単一キーインデックス(Single field index)」「複合キーインデックス (Compound index)」「マルチキーインデックス (Multi-key index)」の使用例を取り上げます。

単一キー インデックス の 作成

以下のようなサンプルドキュメントに対してインデックスを作成するサンプルコードを3通り取り上げます。 MongoDB はドキュメント型データベースなので、RDBにはない「組み込みフィールド」や「組み込みドキュメント」に対するインデックス作成ができます。

{
  "score": 1034,
  "location": { pref: "Kanagawa", city: "Yokohama" }
}

単一フィールド

もっとも単純な「単一フィールド」に対するインデックス作成およびその利用のサンプルコードです。

> db.collection.createIndex({ score: 1 })
> db.collection.find({ score: 1034 })
> db.collection.find({ score: { $gt: 1000 } })

組み込みフィールド

MongoDB では プロパティ の 値 として ドキュメント を指定することもできます。 こうした場合、ドキュメントの中のフィールド(入れ子になった要素)に対してもインデックス作成することができます。

> db.collection.createIndex({ "location.pref": 1 })
> db.collection.find({ "location.pref": "Tokyo" })

組み込みドキュメント

上記の「組み込みフィールド」に似ていますが、そもそもオブジェクトを指定してしまうこともできます。 ただし、この場合はプロパティの数およびプロパティの並び順も含めて完全一致することが求められる点に要注意です。

> db.collection.createIndex({ location: 1 })
> db.collection.find({ pref: "Kanagawa", city: "Yokohama" })

複合キー インデックス の 作成

RDBにも存在する複合キーインデックスです。 MongoDB では 複数フィールド をキーとして指定することで作成できます。 MongoDB の 複合キーインデックス では「指定された 複合キー すべてに一致する」パターンだけでなく、「一部に一致する」パターンでもインデックスが効きます。

以下のサンプルデータに対して「複合キー インデックス」を作成するサンプルを見ていきます。

{
  "item": "Apple",
  "location": "xxx store",
  "stock": 4,
  "type": "cases"
}
> db.collection.createIndex({ item: 1, location: 1, stock: 1 })
> db.collection.find({ item: "Apple" })
> db.collection.find({ item: "Apple", location: "xxx store" })
> db.collection.find({ item: "Apple", location: "xxx store", stock: { $gt: 0 } })

上記の例であれば、インデックスの作成が「item → loation → stock」なので、その先頭一部となる「item」や「item → location」などもインデックスが効きます。

マルチキー インデックス の 作成

MongoDB では 配列 を値としてとるフィールドも存在します。 配列の値は「プリミティブ」もしくは「オブジェクト」のいずれでも「マルチキーインデックス」が作成できます。

以下では 配列フィールド ratings を含むコレクションに対してインデックスの作成、検索を行うサンプルを見ていきます。

{ "item": "Apple",  ratings: [ 2, 9 ] }
{ "item": "Banana", ratings: [ 4, 3 ] }

インデックスの作成は単純に ratings に対して createIndex() するだけで作成できます。

> db.collection.createIndex({ ratings: 1 })

配列フィールドに対する検索は通常 $elemMatch を利用します。 以下のサンプルでは「3以上 かつ 6以下 の ratings が1レコード以上存在するドキュメント」を抽出しています。

> db.collection.find({ ratings: { $elemMatch: { $gte: 3, $lte: 6 } } })
{ "_id" : ObjectId("5a2d24459c684f917e3ec0c2"), "item" : "XYZ", "ratings" : [ 4, 3 ] }

以下のような記載をすると「3以上 または 6以下 を満たすレコードが1件以上存在するドキュメント」を抽出するので、結果としてすべて抽出されてしまいます。

> db.collection.find({ ratings: { $gte: 3, $lte: 6 } })
{ "_id" : ObjectId("5a2d24399c684f917e3ec0c1"), "item" : "ABC", "ratings" : [ 2, 9 ] }
{ "_id" : ObjectId("5a2d24459c684f917e3ec0c2"), "item" : "XYZ", "ratings" : [ 4, 3 ] }

今回は 「MongodB における インデックス の取り扱い」 についてまとめました。 ポイントは以下の通りです。 参考になったでしょうか?

  • インデックスの作成は createIndex()
  • 単一キー、複合キーだけでなくマルチキーと呼ばれるインデックスが存在する

本記事がお役に立っていると嬉しいです!!

参考記事

最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!