Skip to content
bonybeat edited this page Sep 23, 2014 · 36 revisions

OrientDBは4種類のインデックスをサポートしています。

インデックスタイプ 永続性 トランザクション レンジクエリー(範囲検索) 特徴
SBTree YES YES YES バランスが取れている
HashIndex not yet not yet no lookupがすごく高速でディスク上でも軽量
Lucene YES YES YES フルテキストサーチと座標検索
MVRB-Tree no YES YES バージョン1.6以降では非推奨

アルゴリズム上の違いについて、もっと詳しく知りたい場合は、[こちら](Supported Indexing Algorithms)を参考にしてください。

OrientDBはデフォルトのSBTreeアルゴリズムを使うことを推奨しています。

インデックスとは何か?

インデックスは通常二つのプロパティを持っています。 The index is like a class (or table) with 2 properties:

  • インデックス、インデックスキー
  • レコードID、該当するレコードをキーによって参照するためのポインター

インデックスの更新

  • 自動更新、"User.id"のようにスキーマプロパティで定義されている場合。スキーマレスデータベースを利用していてインデックスの自動更新をしたければ、クラスとプロパティを定義します必要があります。
  • 手動更新、Java APIとSQLを利用して開発者が行います(下記参照)。パーシステントMAPとして利用します。

インデックスの種類

インデックスは以下のタイプがあります。一度作成すると変更はできません。

  • SB-Tree アルゴリズム:
  • UNIQUE、重複不可。複合インデックスも利用可能。
  • NOTUNIQUE、重複可。
  • FULLTEXT、 テキストのシングルワードをインデックスとします。CONTAINSTEXTで利用可能。
  • DICTIONARY、UNIQUEに似ているが、キー値がすでに存在していたら新しいもので置き換えられる。
  • HashIndex アルゴリズム
  • UNIQUE_HASH_INDEX、重複不可。複合インデックスも利用可能。
  • NOTUNIQUE_HASH_INDEX、重複可。
  • FULLTEXT_HASH_INDEX、 テキストのシングルワードをインデックスとします。CONTAINSTEXTで利用可能。
  • DICTIONARY_HASH_INDEX、UNIQUEに似ているが、キー値がすでに存在していたら新しいもので置き換えられる。

Dictionary ディクショナリー

すべての単一のデータベースはデフォルトで、dictionaryという名前の"DICTIONARY"タイプのインデックスがある。利用方法としては:

  • treeとgraphのルートレコードを取り扱う
  • 設定のためにシングルトンレコードを取り扱う

インデックスを操作します

Create an index

新しいインデックスを作成します。スキーマプロパティと結びつけるのに"ON"句を使いますが、スキーマは事前に定義しておく必要があります。

Syntax:

CREATE INDEX <name> [ON <class-name> (prop-names)] <type> [<key-type>]
                    [METADATA {<metadata>}]

Where:

  • name、インデックスの論理名。スキーマとそのプロパティは、**<class>.<property>**で指定します。インデックス名に'.'は利用できません。
  • class-name、インデックスを指定しますプロパティを持つクラス名。
  • prop-names、インデックスを指定しますプロパティ。カンマ区切りのリスト。Map型(LINKMAP, EMBEDDEDMAP)に属しますプロパティを指定します場合は、keyまたはvalueのいずれを使用しますかを、
  • type、以下のインデックスタイプのいずれかを指定します:
  • unique、SBTreeを利用します。
  • notunique、SBTreeを利用します。
  • fulltext、、SBTreeを利用します。
  • dictionary、、SBTreeを利用します。
  • unique_hash_index、HashIndexを利用します。
  • notunique_hash_index*、HashIndexを利用します。
  • fulltext_hash_index*、HashIndexを利用します。
  • dictionary_hash_index*、HashIndexを利用します。
  • key-type、オプション。インデックス作成時に対象のスキーマのプロパティを読み込みながら自動的に決定します。
  • metadata、key/valueとしてJSONで表現します追加メタデータ。

カスタムインデックスの例:

CREATE INDEX mostRecentRecords unique date

"User"クラスの"id"プロパティに対して結びつけられた自動インデックスの例:

CREATE PROPERTY User.id BINARY
CREATE INDEX User.id UNIQUE

同様の例の別の書き方:

CREATE INDEX indexForId ON User (id) unique

"Movie"クラスの"thumbs"プロパティのインデックスの例:

CREATE INDEX thumbsAuthor ON Movie (thumbs) unique
CREATE INDEX thumbsAuthor ON Movie (thumbs by key) unique
CREATE INDEX thumbsValue ON Movie (thumbs by value) unique

複合インデックスの例:

CREATE PROPERTY Book.author STRING
CREATE PROPERTY Book.title STRING
CREATE PROPERTY Book.publicationYears EMBEDDEDLIST INTEGER
CREATE INDEX books ON Book (author, title, publicationYears) unique

より詳しい例はこちらを参照して下さい。

インデックスを削除します

インデックスを削除します。リンクされたレコードは削除されない。

Syntax:

DROP INDEX <name>

Where:

  • nameはインデックス名。

より詳しい例はこちらを参照して下さい。

Lookup

要求されたkeyのすべてのレコードを返却します

select from index:<index-name> where key = <key>

サンプル:

select from index:dictionary where key = 'Luke'

新しいエントリィを追加します(インデックスの手動追加)

新しいエントリィをキーレコードIDでインサートします

insert into index:<index-name> (key,rid) values (<key>,<rid>)

Example:

insert into index:dictionary (key,rid) values ('Luke',#10:4)

レンジクエリー(範囲検索)

指定した範囲のキーを取得します

select from index:<index-name> where key between <min> and <max>

Example:

select from index:coordinates where key between 10.3 and 10.7

キーでエントリィを削除します

要求されたキーをもつすべてのエントリィを削除します

delete from index:<index-name> where key = <key>

Example:

delete from index:addressbook where key = 'Luke'

エントリィを削除します

キーレコードIDでエントリィを削除します。削除できたらtrueを返す、対象が見つからなければfalseを返す。

delete from index:<index-name> where key = <key> and rid = <rid>

Example:

delete from index:dictionary where key = 'Luke' and rid = #10:4

レコードへのリファレンスをすべて削除します。

渡されたレコードIDでエントリィをすべて削除します。

delete from index:<index-name> where rid = <rid>

Example:

delete from index:dictionary where rid = #10:4

すべてのエントリィをカウントします

インデックスエントリィのサイズを返す。

select count(*) as size from index:<index-name>

Example:

select count(*) as size from index:dictionary

すべてのキーを取得します

インデックスのすべてのキーを取得します

select key from index:<index-name>

Example:

select key from index:dictionary

すべてのエントリィを取得します

キーレコードIDをペアとしてインデックスのエントリィを取得します

select key, value from index:<index-name>

Example:

select key, value from index:dictionary

インデックスをクリアします

すべてのエントリィを削除します。インデックスはこの処理後は空になります。

delete from index:<index-name>

Example:

delete from index:dictionary

NULL値

デフォルトでインデックスはNULL値を無視します。そのためNULLに対しますクエリーはエントリィを戻しません。

もし、インデックスでNULL値を扱いたいなら、メタデータに{ ignoreNullValues : false }をセットします。

CREATE INDEX addresses ON Employee (address) notunique 
             METADATA {ignoreNullValues : false}

複合インデックス

複合インデックスでも同じ操作ができます

複合キーは値のコレクションです。構文的にはそのように定義されています。例えば、"BOOK"というクラスがあってその三つのレコードをインデックスにします。

  • author,
  • title and
  • publication year

"book"クラスをクエリーするためには以下のようにします。

select from index:books where key = ["Donald Knuth", "The Art of Computer Programming", 1968]

または、publication yearで範囲検索する場合は

select from index:books where key between ["Donald Knuth", "The Art of Computer Programming", 1960] and ["Donald Knuth", "The Art of Computer Programming", 2000]

部分一致による検索

このメカニズムによって、複合キーの先頭フィールドだけでインデックス検索することができます。定義されていない残りのフィールドはどんな値ともマッチします。

複合インデックスは、フィールドが左から右へ構成されている場合だけ、部分一致検索が使えます。上記の例で、 titleだけで検索しようとすると複合インデックスは利用されませんが、authortitleが指定されれば、利用されます。

例えば、本がいつ発行されていてもかまわない場合、以下のようなクエリーを実行すれば、authortitleが一致して、publication yearはどんな値でもよいという結果が取得できます。

select from index:books where key = ["Author", "The Art of Computer Programming"]

titleがわからなければ、authorフィールドだけを指定します。結果として、このauthorのすべての本が取得されます。

select from index:books where key = ["Donald Knuth"]

以下も同じですね。

select from index:books where key = "Donald Knuth"

レンジクエリー 範囲検索

範囲検索の場合は最後のフィールドだけに対して利用できます。

In case of range queries, the field subject to the range must be the last one. Example:

select from index:books where key between ["Donald Knuth", "The Art of Computer Programming", 1900] and ["Donald Knuth", "The Art of Computer Programming", 2014]

複合インデックスに直接インサートする

これはまだサポートされていません。

カスタムキー

OrientDBは1.0以降でインデックスのカスタムキーをサポートしています。これによって、独自のシリアライザーを使用してメモリーを大幅に節約できます。

バイナリーのキーに対して、STRINGを使わないで、SHA-256を利用することでディスク領域やメモリーを節約できます。

独自の型を定義する

    public static class ComparableBinary implements Comparable<ComparableBinary> {
      private byte[]	value;
    
      public ComparableBinary(byte[] buffer) {
        value = buffer;
      }
    
      public int compareTo(ComparableBinary o) {
        final int size = value.length;
        for (int i = 0; i < size; ++i) {
          if (value[i] > o.value[i])
    	return 1;
          else if (value[i] < o.value[i])
            return -1;
        }
        return 0;
      }
    
      public byte[] toByteArray() {
        return value;
      }
    }

独自のバイナリーシリアライザーを作成する

    public static class OHash256Serializer implements OBinarySerializer<ComparableBinary> {
    
      public static final OBinaryTypeSerializer INSTANCE = new OBinaryTypeSerializer();
      public static final byte ID = 100;
      public static final int LENGTH = 32;
    
      public int getObjectSize(final int length) {
        return length;
      }
    
      public int getObjectSize(final ComparableBinary object) {
        return object.toByteArray().length;
      }
    
      public void serialize(final ComparableBinary object, final byte[] stream, final int startPosition) {
        final byte[] buffer = object.toByteArray();
        System.arraycopy(buffer, 0, stream, startPosition, buffer.length);
      }
    
      public ComparableBinary deserialize(final byte[] stream, final int startPosition) {
        final byte[] buffer = Arrays.copyOfRange(stream, startPosition, startPosition + LENGTH);
        return new ComparableBinary(buffer);
      }
    
      public int getObjectSize(byte[] stream, int startPosition) {
        return LENGTH;
      }
    
      public byte getId() {
        return ID;
      }
    }

独自にシリアライザーを登録する

OBinarySerializerFactory.INSTANCE.registerSerializer(new OHash256Serializer(), null);
index = database.getMetadata().getIndexManager().createIndex("custom-hash", "UNIQUE", new ORuntimeKeyIndexDefinition(OHash256Serializer.ID), null, null);

使用方法

ComparableBinary key1 = new ComparableBinary(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 });
ODocument doc1 = new ODocument().field("k", "key1");
index.put(key1, doc1);

ティップス

インデックスのリストを取得する

OrientDB1.6以上:

select flatten(indexes) from metadata:indexmanager

-->

OrientDB1.0以上:

select flatten(indexes) from cluster:0

-->

独自にインデックスエンジンを作る

こちらを参照して独自のインデックスエンジンを作成する参考にしてください。

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script> <script> $(function() { $("*").contents().filter(function() { return this.nodeType==8 && this.nodeValue.match(/^original/); }).each(function(i, e) { var tooltips = e.nodeValue.replace(/^original *[\n\r]|[\n\r]$/g, ''); $(this).prev().attr('title', tooltips); }); }); </script>
Clone this wiki locally