マップの索引付け
マップにスカラー・データが含まれる、またはスカラー・フィールド付きのレコードが含まれる場合には、マップ・フィールドに索引を作成できます。
注意:
別のマップまたは配列の下にネストされたマップまたは配列には索引付けできません。これができないのは、索引エントリの数が極端に多くなる可能性があるからです。
索引を作成するには、マップを通常のマップとして定義します。表にマップが定義された後、表に索引付けする方法はいくつかあります。
-
実際のキー値にかかわらず、マップのキーに基づく方法。
-
実際に使用されるキーにかかわらず、マップの値に基づく方法。
-
特定のマップ・キーに基づく方法。この方法で実行するために、マップ・フィールドの名前を指定し、さらに、ドット表記法を使用してマップ・キーの名前を指定します。マップ・キーがクライアント・コードを使用して作成されている場合は、索引付けされます。
-
具体的な値(このリストの前のオプションで要求されているような値)を識別することなく、マップのキーおよび値に基づく方法。
マップ・キーによる索引付け
対応する値にかかわらず、マップのキーに基づいて索引を作成できます。
このような索引を作成すると、場合によっては各行に複数の索引エントリになり、かなり大きな索引になる可能性があることに注意してください。
最初に表を作成します。
CREATE TABLE myMapTable (
uid INTEGER,
testMap MAP(INTEGER),
PRIMARY KEY(uid)
)
表がストアに追加された後、.keys()
パス・ステップを使用して索引を作成します。
CREATE INDEX mapKeyIndex on myMapTable (testMap.keys())
指定したキーが付いた指定したマップが表の行に含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、
...
def writeStore(store, row_d):
try:
store.put("myMapTable", row_d)
logging.debug("Store write succeeded.")
except IllegalArgumentException, iae:
logging.error("Could not write table.")
logging.error(iae.message)
sys.exit(-1)
...
def populateTable(store):
row_d = {'uid' : 12345,
'testMap' : {'field1' : 1, 'field2' : 2, 'field3' : 3}
}
writeStore(store, row_d)
row_d = {'uid' : 12,
'testMap' : {'field1' : 1, 'field2' : 2}
}
writeStore(store, row_d)
row_d = {'uid' : 666,
'testMap' : {'field1' : 1, 'field3' : 4}
}
writeStore(store, row_d)
現在マップで使用中の任意のキーが付いたマップを含む任意の表の行を取得できます。たとえば、「field3」です。
マップを表すために単純なPythonディクショナリを使用します。使用する索引はマップのキーに基づいているため、マップの値には単純にNone
を使用できます。
def readStore(store):
try:
key_d = {"testMap" : {'field3' : None}}
row_list = store.index_iterator("myMapTable",
"mapKeyIndex",
key_d,
False)
if not row_list:
logging.debug("Table retrieval failed")
else:
logging.debug("Table retrieval succeeded.")
for r in row_list:
print r
except IllegalArgumentException, iae:
logging.error("Table retrieval failed.")
logging.error(iae.message)
マップ値による索引付け
使用中のキーに関係なく、マップに含まれる値に基づき、索引を作成できます。
このような索引を作成すると、場合によっては各行に複数の索引エントリになり、かなり大きな索引になる可能性があることに注意してください。
最初に表を作成します。
CREATE TABLE myMapTable (
uid INTEGER,
testMap MAP(INTEGER),
PRIMARY KEY(uid)
)
表がストアに追加された後、.values()
パス・ステップを使用して索引を作成します。
CREATE INDEX mapElementIndex on myMapTable (testMap.values())
指定した値が付いた指定したマップが表の行に含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、
...
def writeStore(store, row_d):
try:
store.put("myMapTable", row_d)
logging.debug("Store write succeeded.")
except IllegalArgumentException, iae:
logging.error("Could not write table.")
logging.error(iae.message)
sys.exit(-1)
...
def populateTable(store):
row_d = {'uid' : 12345,
'testMap' : {'field1' : 1, 'field2' : 2, 'field3' : 3}
}
writeStore(store, row_d)
row_d = {'uid' : 12,
'testMap' : {'field1' : 1, 'field2' : 2}
}
writeStore(store, row_d)
row_d = {'uid' : 666,
'testMap' : {'field1' : 1, 'field3' : 4}
}
writeStore(store, row_d)
現在マップで使用中の任意の値が付いたマップを含む任意の表の行を取得できます。たとえば、値「2」です。
次の例では、索引キーのフィールド値に特殊文字列"[]"を使用しています。フィールド名はその文字列である必要があり、そうでない場合、適切な索引にアクセスできません。
def readStore(store):
try:
key_d = {"testMap" : {"[]" : 2}}
row_list = store.index_iterator("myMapTable",
"mapElementIndex",
key_d,
False)
if not row_list:
logging.debug("Table retrieval failed")
else:
logging.debug("Table retrieval succeeded.")
for r in row_list:
print r
except IllegalArgumentException, iae:
logging.error("Table retrieval failed.")
logging.error(iae.message)
特定のマップ・キー名による索引付け
指定したマップ・キー名に基づいて索引を作成できます。指定したキー名を含むあらゆるマップ・エントリは索引付けされます。索引にはマップ・フィールドに含まれるすべてのキー/値ペアが含まれるわけではないため、小さくて効率的な索引を作成できます。かわりに、識別されたキーを使用するマップ・エントリのみを含むため、結果として多くても各行に1つの索引エントリになります。
索引を作成するには、まず表を作成します。
CREATE TABLE myMapTable (
uid INTEGER,
testMap MAP(INTEGER),
PRIMARY KEY(uid)
)
テーブルがストアに追加された後、ドット表記法を使用して索引付けするキー名を指定して索引を作成します。この例では、「field3」という名前のキーを索引付けします。
CREATE INDEX mapField3Index on myMapTable (testMap.field3)
表の行に索引付けされたキーと特定の値の付いた指定したマップが含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、
...
def writeStore(store, row_d):
try:
store.put("myMapTable", row_d)
logging.debug("Store write succeeded.")
except IllegalArgumentException, iae:
logging.error("Could not write table.")
logging.error(iae.message)
sys.exit(-1)
...
def populateTable(store):
row_d = {'uid' : 12345,
'testMap' : {'field1' : 1, 'field2' : 2, 'field3' : 3}
}
writeStore(store, row_d)
row_d = {'uid' : 12,
'testMap' : {'field1' : 1, 'field2' : 2}
}
writeStore(store, row_d)
row_d = {'uid' : 666,
'testMap' : {'field1' : 1, 'field3' : 4}
}
writeStore(store, row_d)
「field3」が特定の値(たとえば、「3」)にマップされるとき、キー「field3」が付いたマップ(これが索引付けしたものであるため)を含む任意の表の行を取得できます。たとえば、「field2」に対して索引参照を実行すると、「field2」は索引付けしていないため、失敗します。
def readStore(store):
try:
key_d = {"testMap" : {"field3" : 3}}
row_list = store.index_iterator("myMapTable",
"mapField3Index",
key_d,
False)
if not row_list:
logging.debug("Table retrieval failed")
else:
logging.debug("Table retrieval succeeded.")
for r in row_list:
print r
except IllegalArgumentException, iae:
logging.error("Table retrieval failed.")
logging.error(iae.message)
マップ・キーおよび値による索引付け
前の項で、事前定義済キー名を指定することでマップ索引を作成する方法を示しました。これにより、キーと値の両方を指定してマップ索引参照が可能ですが、指定したキーが索引付けしたキーの場合のみ索引参照が成功します。
マップ内のすべてのキー/値ペアを索引付けすることで、同じことを汎用的な方法で実行できます。結果としてさらに柔軟な索引になりますが、前に説明したメソッドよりも大きな索引になる可能性があります。結果として各行に複数の索引となる可能性が高くなります。
マップ・フィールドによって使用される各キー/値ペアに基づく索引を作成するには、まず表を作成します。
CREATE TABLE myMapTable (
uid INTEGER,
testMap MAP(INTEGER),
PRIMARY KEY(uid)
)
表がストアに追加された後、.keys()
および.values()
パス・ステップを使用して索引を作成します。
CREATE INDEX mapKeyValueIndex on myMapTable
(testMap.keys(),testMap.values())
指定したキーおよび指定した値の付いた指定したマップが表の行に含まれている場合、データが取得されます。つまり、たとえば、次のような一連の表の行を作成する場合、
...
def writeStore(store, row_d):
try:
store.put("myMapTable", row_d)
logging.debug("Store write succeeded.")
except IllegalArgumentException, iae:
logging.error("Could not write table.")
logging.error(iae.message)
sys.exit(-1)
...
def populateTable(store):
row_d = {'uid' : 12345,
'testMap' : {'field1' : 1, 'field2' : 2, 'field3' : 3}
}
writeStore(store, row_d)
row_d = {'uid' : 12,
'testMap' : {'field1' : 1, 'field2' : 2}
}
writeStore(store, row_d)
row_d = {'uid' : 666,
'testMap' : {'field1' : 1, 'field3' : 4}
}
writeStore(store, row_d)
指定したキー/値ペア(たとえば、キー「field3」および値「3」)が付いたマップを含む任意の表の行を取得できます。
この種類の索引に基づいて取得するには、次のものを指定する必要があります。
-
必要なマップ値を持つ特殊文字列[]
-
マップ値に対する
None
を持つフィールド名。
これは、次のようにしてPythonで行います。
def readStore(store):
try:
key_d = {"testMap" : {"[]" : 3, "field3" : None}}
row_list = store.index_iterator("myMapTable",
"mapKeyValueIndex",
key_d,
False)
if not row_list:
logging.debug("Table retrieval failed")
else:
logging.debug("Table retrieval succeeded.")
for r in row_list:
print r
except IllegalArgumentException, iae:
logging.error("Table retrieval failed.")
logging.error(iae.message)