マップの索引付け

マップ・キーによる索引付け
マップ値による索引付け
特定のマップ・キー名による索引付け
マップ・キーおよび値による索引付け

マップにスカラー・データが含まれる、またはスカラー・フィールド付きのレコードが含まれる場合には、マップ・フィールドに索引を作成できます。

注意

別のマップまたは配列の下にネストされたマップまたは配列には索引付けできません。これができないのは、索引エントリの数が極端に多くなる可能性があるからです。

索引を作成するには、マップを通常のマップとして定義します。表にマップが定義された後、表に索引付けする方法はいくつかあります。

マップ・キーによる索引付け

対応する値にかかわらず、マップのキーに基づいて索引を作成できます。

このような索引を作成すると、場合によっては各行に複数の索引エントリになり、かなり大きな索引になる可能性があることに注意してください。さらに、結果セットに同じ行が表れる可能性があり、アプリケーションは重複エントリを扱う必要がでてきます。

最初に表を作成します。

CREATE TABLE myMapTable (
    uid INTEGER,
    testMap MAP(INTEGER),
    PRIMARY KEY(uid)
) 

表がストアに追加された後、KEYOF文を使用して索引を作成します。

CREATE INDEX mapKeyIndex on myMapTable (KEYOF(testMap)) 

指定したキーが付いた指定したマップが表の行に含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、

TableAPI tableH = kvstore.getTableAPI();

Table myTable = tableH.getTable("myMapTable");

Row row = myTable.createRow();
row.put("uid", 12345);
MapValue mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
mv.put("field3", 3);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 12);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 666);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field3", 4);
tableH.put(row, null, null); 

現在マップで使用中の任意のキーが付いたマップを含む任意の表の行を取得できます。たとえば、「field3」です。

マップ索引を使用してデータを取得するには、まず名前を使用して索引を取得し、索引参照の実行に使用するIndexKeyのインスタンスを作成します。

Index mapIndex = myTable.getIndex("mapKeyIndex");
IndexKey indexKey = mapIndex.createIndexKey(); 

次に、MapValue.putNull()メソッドを使用して、MapValueインスタンスを作成して、指定します。このメソッドによって、エントリの値部分に関係なくマップ・エントリを取得できます。索引参照を実行するとき、戻されるレコードは指定したキー名付きのマップがあるレコードのみです。

MapValue mv = indexKey.putMap("testMap");
mv.putNull("field3"); 

その後、一致する表の行を取得し、別の索引タイプと同じ方法で繰り返します。次に例を示します。

TableIterator<Row> iter = tableH.tableIterator(indexKey, null, null);
System.out.println("Results for testMap field3: ");
try {
    while (iter.hasNext()) {
        Row rowRet = iter.next();
        int uid = rowRet.get("uid").asInteger().get();
        System.out.println("uid: " + uid);
        MapValue mapRet = rowRet.get("testMap").asMap();
        System.out.println("testMap: " + mapRet.toString());
    }
} finally {
    if (iter != null) {
        iter.close();
    }
} 

マップ値による索引付け

使用中のキーに関係なく、マップに含まれる値に基づき、索引を作成できます。

このような索引を作成すると、場合によっては各行に複数の索引エントリになり、かなり大きな索引になる可能性があることに注意してください。さらに、結果セットに同じ行が表れる可能性があり、アプリケーションは重複エントリを扱う必要がでてきます。

最初に表を作成します。

CREATE TABLE myMapTable (
    uid INTEGER,
    testMap MAP(INTEGER),
    PRIMARY KEY(uid)
) 

テーブルがストアに追加された後、ELEMENTOF文を使用して索引を作成します。

CREATE INDEX mapElementIndex on myMapTable (ELEMENTOF(testMap)) 

指定した値が付いた指定したマップが表の行に含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、

TableAPI tableH = kvstore.getTableAPI();

Table myTable = tableH.getTable("myMapTable");

Row row = myTable.createRow();
row.put("uid", 12345);
MapValue mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
mv.put("field3", 3);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 12);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 666);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field3", 4);
tableH.put(row, null, null); 

現在マップで使用中の任意の値が付いたマップを含む任意の表の行を取得できます。たとえば、値「2」です。

マップ索引を使用してデータを取得するには、まず名前を使用して索引を取得し、索引参照の実行に使用するIndexKeyのインスタンスを作成します。

Index mapIndex = myTable.getIndex("mapElementIndex");
IndexKey indexKey = mapIndex.createIndexKey(); 

次に、MapValue.put()メソッドを使用してMapValueインスタンスを作成して、指定します。このメソッドのkey値では、MapValue.ANONYMOUSを使用します。valueフィールドには、2を指定します。索引参照を実行するとき、戻されるレコードは値2のマップがあるレコードのみです。

MapValue mv = indexKey.putMap("testMap");
mv.put(MapValue.ANONYMOUS, 2); 

その後、一致する表の行を取得し、別の索引タイプと同じ方法で繰り返します。次に例を示します。

TableIterator<Row> iter = tableH.tableIterator(indexKey, null, null);
System.out.println("Results for testMap value 2: ");
try {
    while (iter.hasNext()) {
        Row rowRet = iter.next();
        int uid = rowRet.get("uid").asInteger().get();
        System.out.println("uid: " + uid);
        MapValue mapRet = rowRet.get("testMap").asMap();
        System.out.println("testMap: " + mapRet.toString());
    }
} finally {
    if (iter != null) {
        iter.close();
    }
} 

特定のマップ・キー名による索引付け

指定したマップ・キー名に基づいて索引を作成できます。指定したキー名を含むあらゆるマップ・エントリは索引付けされます。索引にはマップ・フィールドに含まれるすべてのキー/値ペアが含まれるわけではないため、小さくて効率的な索引を作成できます。かわりに、識別されたキーを使用するマップ・エントリのみを含むため、結果として多くても各行に1つの索引エントリになります。

索引を作成するには、まず表を作成します。

CREATE TABLE myMapTable (
    uid INTEGER,
    testMap MAP(INTEGER),
    PRIMARY KEY(uid)
) 

テーブルがストアに追加された後、ドット表記法を使用して索引付けするキー名を指定して索引を作成します。この例では、「field3」という名前のキーを索引付けします。

CREATE INDEX mapFieldIndex on myMapTable (testMap.field3) 

表の行に索引付けされたキーと特定の値の付いた指定したマップが含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、

TableAPI tableH = kvstore.getTableAPI();

Table myTable = tableH.getTable("myMapTable");

Row row = myTable.createRow();
row.put("uid", 12345);
MapValue mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
mv.put("field3", 3);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 12);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 666);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field3", 4);
tableH.put(row, null, null); 

「field3」が特定の値(たとえば、「3」)にマップされるとき、キー「field3」が付いたマップ(これが索引付けしたものであるため)を含む任意の表の行を取得できます。たとえば、「field2」に対して索引参照を実行すると、「field2」は索引付けしていないため、失敗します。

マップ索引を使用してデータを取得するには、まず名前を使用して索引を取得し、索引参照の実行に使用するIndexKeyのインスタンスを作成します。

Index mapIndex = myTable.getIndex("mapFieldIndex");
IndexKey indexKey = mapIndex.createIndexKey(); 

次に、MapValue.put()を使用してMapValueインスタンスを作成して、指定します。索引参照を実行するとき、戻されるレコードは一致するキー名および対応する値付きのマップがあるレコードのみです。

MapValue mv = indexKey.putMap("testMap");
mv.put("field3", 3); 

その後、一致する表の行を取得し、別の索引タイプと同じ方法で繰り返します。次に例を示します。

TableIterator<Row> iter = tableH.tableIterator(indexKey, null, null);
System.out.println("Results for testMap field3, value 3: ");
try {
    while (iter.hasNext()) {
        Row rowRet = iter.next();
        int uid = rowRet.get("uid").asInteger().get();
        System.out.println("uid: " + uid);
        MapValue mapRet = rowRet.get("testMap").asMap();
        System.out.println("testMap: " + mapRet.toString());
    }
} finally {
    if (iter != null) {
        iter.close();
    }
} 

マップ・キーおよび値による索引付け

前の項で、事前定義済キー名を指定することでマップ索引を作成する方法を示しました。これにより、キーと値の両方を指定してマップ索引参照が可能ですが、指定したキーが索引付けしたキーの場合のみ索引参照が成功します。

マップ内のすべてのキー/値ペアを索引付けすることで、同じことを汎用的な方法で実行できます。結果としてさらに柔軟な索引になりますが、前に説明したメソッドよりも大きな索引になる可能性があります。結果として各行に複数の索引となる可能性が高くなります。

マップ・フィールドによって使用される各キー/値ペアに基づく索引を作成するには、まず表を作成します。

CREATE TABLE myMapTable (
    uid INTEGER,
    testMap MAP(INTEGER),
    PRIMARY KEY(uid)
) 

テーブルがストアに追加された後、KEYOFおよびELEMENTOFキーワードを使用して索引を作成します。

CREATE INDEX mapKeyValueIndex on myMapTable \
(KEYOF(testMap),ELEMENTOF(testmap)) 

指定したキーおよび指定した値の付いた指定したマップが表の行に含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、

TableAPI tableH = kvstore.getTableAPI();

Table myTable = tableH.getTable("myMapTable");

Row row = myTable.createRow();
row.put("uid", 12345);
MapValue mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
mv.put("field3", 3);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 12);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field2", 2);
tableH.put(row, null, null);

row = myTable.createRow();
row.put("uid", 666);
mv = row.putMap("testMap");
mv.put("field1", 1);
mv.put("field3", 4);
tableH.put(row, null, null); 

指定したキー/値ペア(たとえば、キー「field3」および値「3」)が付いたマップを含む任意の表の行を取得できます。

マップ索引を使用してデータを取得するには、まず名前を使用して索引を取得し、索引参照の実行に使用するIndexKeyのインスタンスを作成します。

Index mapIndex = myTable.getIndex("mapKeyValueIndex");
IndexKey indexKey = mapIndex.createIndexKey(); 

次に、MapValue.put()を使用してMapValueインスタンスを作成して、指定します。索引参照を実行するとき、戻されるレコードは一致するキー/値ペア付きのマップがあるレコードのみです。

MapValue mv = indexKey.putMap("testMap");
mv.putNull("field3");
mv.put(MapValue.ANONYMOUS, 3); 

その後、一致する表の行を取得し、別の索引タイプと同じ方法で繰り返します。次に例を示します。

TableIterator<Row> iter = tableH.tableIterator(indexKey, null, null);
System.out.println("Results for testMap field3, value 3: ");
try {
    while (iter.hasNext()) {
        Row rowRet = iter.next();
        int uid = rowRet.get("uid").asInteger().get();
        System.out.println("uid: " + uid);
        MapValue mapRet = rowRet.get("testMap").asMap();
        System.out.println("testMap: " + mapRet.toString());
    }
} finally {
    if (iter != null) {
        iter.close();
    }
}