マップの索引付け

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

注意:

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

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

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

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

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

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

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

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

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

最初に表を作成します。

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

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

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

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

function writeRow(store, uid, map) {

   var row = {
       uid: uid,
       testMap: map
   };
   store.put('myMapTable', row,
           function (err) {
                if (err)
                    throw err;
                else {
                    console.log("Row inserted.");
                }
           });
}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');

   writeRow(store, 12345, {field1: 1, field2: 2, field3: 3});
   writeRow(store, 12, {field1: 1, field2: 2});
   writeRow(store, 666, {field1: 1, field3: 4});

   store.close();

}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open(); 

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

マップを表現するために、単純なJavascriptオブジェクトを使用します。使用する索引はマップのキーに基づいているため、マップのキー値に必要な任意の値を指定できます。ここでは、nullのみを使用しますが、他の値を指定した場合も結果は同じになります。

function getIndexByFieldName(store, fieldName) {
   var obj = {}
   obj[fieldName] = null;
   var indexKey1 = {testMap: obj}

   store.indexIterator('myMapTable', 'mapKeyIndex',      
        {indexKey: indexKey1},
        function (err, iterator) {
              iterator.forEach(function (err, currentRow) {
                 console.log(currentRow.row);
              });
        }
    );

}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');

   getIndexByFieldName(store, "field3");

   store.close();

}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open(); 

マップ値による索引付け

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

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

最初に表を作成します。

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

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

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

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

function writeRow(store, uid, map) {

   var row = {
       uid: uid,
       testMap: map
   };
   store.put('myMapTable', row,
           function (err) {
                if (err)
                    throw err;
                else {
                    console.log("Row inserted.");
                }
           });
}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');

   writeRow(store, 12345, {field1: 1, field2: 2, field3: 3});
   writeRow(store, 12, {field1: 1, field2: 2});
   writeRow(store, 666, {field1: 1, field3: 4});

   store.close();

}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open(); 

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

次の例では、索引キーのフィールド値に特殊文字列"[]"を使用しています。フィールド名はその文字列である必要があり、そうでない場合、適切な索引にアクセスできません。

function getIndexByMapValue(store, mv) {
   var obj = {};
   obj["[]"] = mv;
   var indexKey1 = {testMap: obj };

   store.indexIterator('myMapTable', 'mapElementIndex',
        {indexKey: indexKey1},
        function (err, iterator) {
              iterator.forEach(function (err, currentRow) {
                 console.log(currentRow.row);
              });
        }
    );

}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   getIndexByMapValue(store, 2);
   store.close();
}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open(); 

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

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

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

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

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

CREATE INDEX mapField3Index on myMapTable (testMap.field3) 

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

function writeRow(store, uid, map) {

   var row = {
       uid: uid,
       testMap: map
   };
   store.put('myMapTable', row,
           function (err) {
                if (err)
                    throw err;
                else {
                    console.log("Row inserted.");
                }
           });
}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');

   writeRow(store, 12345, {field1: 1, field2: 2, field3: 3});
   writeRow(store, 12, {field1: 1, field2: 2});
   writeRow(store, 666, {field1: 1, field3: 4});

   store.close();

}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open(); 

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

function getIndexByField3KeyName(store, mv) {
  var indexKey1 = {testMap: {field3: mv}};

   store.indexIterator('myMapTable', 'mapField3Index',
        {indexKey: indexKey1},
        function (err, iterator) {
              iterator.forEach(function (err, currentRow) {
                 console.log(currentRow.row);
              });
        }
    );

}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');
   getIndexByField3KeyName(store, 3);
   store.close();
}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open(); 

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

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

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

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

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

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

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

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

function writeRow(store, uid, map) {

   var row = {
       uid: uid,
       testMap: map
   };
   store.put('myMapTable', row,
           function (err) {
                if (err)
                    throw err;
                else {
                    console.log("Row inserted.");
                }
           });
}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');

   writeRow(store, 12345, {field1: 1, field2: 2, field3: 3});
   writeRow(store, 12, {field1: 1, field2: 2});
   writeRow(store, 666, {field1: 1, field3: 4});

   store.close();

}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open(); 

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

この種類の索引に基づいて取得するには、次のものを指定する必要があります。

  • 必要なマップ値を持つ特殊文字列[]

  • マップ値nullを持つフィールド名。

これはnode.jsで次のようにします。

function getIndexByKeyAndValue(store, fn, mv) {

   // declare and initialize the object
   var indexKey1 = {};
   indexKey1["testMap"] = {};

   // Now set the information to the object so that the
   // proper index is used, and data is retrieved by our
   // desired values.
   indexKey1.testMap["[]"] = mv;  // set the map value
   indexKey1.testMap[fn] = null;  // set the field name

   store.indexIterator('myMapTable', 'mapKeyValueIndex',
        {indexKey: indexKey1},
        function (err, iterator) {
              iterator.forEach(function (err, currentRow) {
                 console.log(currentRow.row);
              });
        }
    );

}

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');
   getIndexByKeyAndValue(store, "field3", 3);
   store.close();
}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open();