マップの索引付け

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

ノート:

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

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

  • 実際のキー値にかかわらず、マップのキーに基づく方法。

  • 実際に使用されるキーにかかわらず、マップの値に基づく方法。

  • 特定のマップ・キーに基づく方法。この方法で実行するために、マップ・フィールドの名前を指定し、さらに、ドット表記法を使用してマップ・キーの名前を指定します。マップ・キーがクライアント・コードを使用して作成されている場合は、索引付けされます。

  • 具体的な値(このリストの前のオプションで要求されているような値)を識別することなく、マップのキーおよび値に基づく方法。

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

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

このような索引を作成すると、場合によっては各行に複数の索引エントリになり、かなり大きな索引になる可能性があることに注意してください。

最初に表を作成します。

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

表がストアに追加された後、.keys()パス・ステップを使用して索引を作成します。

CREATE INDEX mapKeyIndex on myMapTable (testMap.keys()) 

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

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(); 

次に、取得するフィールド名をIndexKeyインスタンスに移入します。keys()パス・ステップを使用して、フィールド値を考慮せずにフィールド名を使用して取得することを指定します。索引参照を実行するとき、戻されるレコードは指定したキー名付きのマップがあるレコードのみです。

indexKey.put("testMap.keys()", "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)
) 

表がストアに追加された後、.values()パス・ステップを使用して索引を作成します。

CREATE INDEX mapElementIndex on myMapTable (testMap.values())

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

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(); 

次に、取得するフィールド値(2)をIndexKeyインスタンスに移入します。フィールド名を持つvalues()パス・ステップを使用して、値のみに基づいてエントリを取得することを指定します。索引参照を実行するとき、戻されるレコードは値2のマップがあるレコードのみです。

indexKey.put("testMap.values()", 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 mapField3Index 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("mapField3Index");
IndexKey indexKey = mapIndex.createIndexKey(); 

次に、IndexKey.put()を使用して、マップ・フィールド名(ドット表記法を使用)および目的の値を移入します。索引参照を実行するとき、戻されるレコードは一致するキー名および対応する値付きのマップがあるレコードのみです。

indexKey.put("testMap.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)
) 

表がストアに追加された後、.keys()および.values()パス・ステップを使用して索引を作成します。

CREATE INDEX mapKeyValueIndex on myMapTable 
(testMap.keys(),testMap.values())

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

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(); 

次に、取得するフィールド名および値をIndexKeyクラス・インスタンスに移入します。この場合、IndexKey.put()の2つのコールを使用して、2つのセットの情報を指定する必要があります。

  • フィールドの名前。ここで、フィールド名を指定してkeys()パス・ステップを使用します。

  • 取得するフィールド値。ここで、フィールド名を指定してvalues()パス・ステップを使用します。

次に例を示します。

indexKey.put("testMap.keys()", "field3");
indexKey.put("testMap.values()", 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();
    }
}