IndexedDBにはまってます。(その21)で予告の通り、インデックスキー(補キー)登録の指定について、その実際を紹介します。
今回もコピペコード全てをテキストファイル「code_IndexedDB_22.txt.zip」にまとめてアップロードしました。ご利用ください。
(その19)でインデックスキー(補キー)の指定項目の説明をしてます。はまってシリーズでは、つぎのような連想配列による指定セットを配列にして準備してます。
const storeIndex = [
{name:'indexEn', path:'index.en', unique:false, multi:false},
...
]
これらの値はインデックスキー(補キー)を登録するcreateIndexメソッドのパラメータに割り当てます。パラメータは(その19)で紹介した通り、つぎのようになります。
objectStore.createIndex(登録名文字列, パス文字列, {unique:真偽値, multiEntry:真偽値});
‘storeIndex[].name’は、第一パラメータに割り当て「登録名(name)」になります。
‘storeIndex[].path’は、第二パラメータに割り当て「パス(keyPath)」になります。
第三パラメータは連想配列です。
‘storeIndex[].unique’は、第三パラメータのuniqueの値に割り当て一意に運用するための「真偽値」になります。
‘storeIndex[].multi’は、第三パラメータのmultiEntryの値に割り当てマルチエントリーの当否の「真偽値」になります。
第一第二パラメータは(その19)を確認してください。ここでは第三パラメータについて確認していきます。
今回も説明の都合上、つぎの登録用配列を利用します。Webブラウザ(Google Chromeを利用)のコンソールにコピー&ペーストし、エンターキーで登録します。
コピペコードファイルの「登録用インデックスキー(補キー)の配列」です。
const storeIndex = [
{name:'indexEn', path:'index.en', unique:false, multi:false},
{name:'indexSn', path:'index.sn', unique:false, multi:false},
{name:'id', path:'id', unique:true, multi:false},
{name:'attributeArray', path:['attribute','note'], unique:true, multi:false},
{name:'indexArray', path:['index.en','id'], unique:false, multi:false},
{name:'tagMulti', path:'tag', unique:false, multi:true}
];
検証を始める前に、指定において注意が一つあります。私の調査の範疇では、この情報はどこにもありませんでした。
(注意)インデックスキー(補キー)のパスに配列を指定した場合は、マルチエントリーを真にできません。よって上記の登録用配列の最後の要素をつぎの様には指定できません。
{name:'multiArray', path:['id','tag'], unique:false, multi:true}
実行してみると、createIndexメソッドを参照したときに例外が発生します。
例外の発生を確認する前は「これってどうやって運用できるのやら…。」と恐れ、ワクワクしていたのですが残念(ほっ)だめでした。考えてみれば「ちょっと無理系。」でしたか。
それでは’unique’から紹介しましょう。
‘unique’
先にインデックスキー(補キー)登録用配列を登録してありますから、オブジェクトストアの生成と共にその登録を実行し、つづけてレコード格納用配列を登録して、レコードを格納します。IndexedDBにはまってます。(その21)の前半のくだりです。
コピペコードファイルの「オブジェクトストア生成と共にインデックスキー(補キー)を登録」を実行し、「レコードの配列」(つぎの配列)を登録して、つづく「レコードの格納」を実行します。
const records = [
{key:2, data:{index:{en:1, sn:'SN0003'}, date:0, title:'ZINC', attribute:'transition', tag:['plate','Zn','shingle','brass'], note:'Zn', id:2}},
{key:6, data:{index:{en:2, sn:'SN0001'}, date:0, title:'GOLD', attribute:'transition', tag:['coin','jewelry','plate','Au','finger'], note:'Au', id:6}},
{key:5, data:{index:{en:3, sn:'SN0002'}, date:0, title:'SILVER', attribute:'transition', tag:['coin','jewelry','plate','tableware'], note:'Ag', id:5}},
{key:7, data:{index:{en:4, sn:'SN0004'}, date:0, title:'PLATIUM', attribute:'transition', tag:['css','jewelry','plate','catalyst'], note:'Pt', id:7}},
{key:1, data:{index:{en:5, sn:'SN0005'}, date:0, title:'COPPER', attribute:'transition', tag:['coin','pans','plate','shingle','brass'], note:'Cu', id:1}},
{key:3, data:{index:{en:6, sn:'SN0006'}, date:0, title:'ALUMINUM', attribute:'post-transition', tag:['coin','sash','pans','Macbook'], note:'Al', id:3}}
];


つぎの格納(追加)用配列を登録します。第一要素の末尾、わざと「id:7」と値を被らせてあります。
コピペコードファイルの「レコードの配列(追加)」(つぎの配列)を登録して、再度「レコードの格納」を実行します。
const records = [
{key:9, data:{index:{en:7, sn:'SN0009'}, date:0, title:'TIN', attribute:'post-transition', tag:['pewter','cup','plate','suzunari'], note:'Sn', id:7}},
{key:4, data:{index:{en:9, sn:'SN0011'}, date:0, title:'LEAD', attribute:'post-transition', tag:['solder','bullet','glass','battery'], note:'Pb', id:9}}
]

プライマリキー(主キー)が異なってもインデックスキー(補キー)の一意が守られて例外が発生します。
では、上書きしてしまうputメソッドでどうでしょう。
プライマリキー(主キー)が異なっていたら上書きはされません(でした。)が、つぎのように同じ「index:{en:4, sn:’SN0004′}」にして試してみたらしっかり上書きしてくれました。
ただし、「id:3」とか一意を守れない値にすると例外となりました。正しいですね。(このputメソッドのくだりは、ウザいのでコピペコードファイルから外してあります。悪しからず。)
const records = [
{key:9, data:{index:{en:4, sn:'SN0004'}, date:0, title:'TIN', attribute:'post-transition', tag:['pewter','cup','plate','suzunari'], note:'Sn', id:7}},
{key:4, data:{index:{en:9, sn:'SN0011'}, date:0, title:'LEAD', attribute:'post-transition', tag:['solder','bullet','glass','battery'], note:'Pb', id:9}}
]


それでは、格納(追加)用配列の「id:7」を「id:8」に訂正&登録して、レコードを格納します。
コピペコードファイルの「レコードの配列(訂正版)」(つぎの配列)を登録して、再度「レコードの格納」を実行します。
const records = [
{key:9, data:{index:{en:7, sn:'SN0009'}, date:0, title:'TIN', attribute:'post-transition', tag:['pewter','cup','plate','suzunari'], note:'Sn', id:8}},
{key:4, data:{index:{en:9, sn:'SN0011'}, date:0, title:'LEAD', attribute:'post-transition', tag:['solder','bullet','glass','battery'], note:'Pb', id:9}}
]

役者が揃いましたので、レコードの参照をしてみます。
パスを配列で登録した’attributeArray’でテストします。’unique’を真で指定してますが、配列全体の値に被りはないために問題は生じてません。アプリケーション画面のオブジェクトストアのインデックス(補キー)「attributeArray」の項目をアクティブにして確認ができます。

それではラングオブジェクトを生成し、getAllメソッドを利用してレコードを取得します
IndexedDBにはまってます。(その21)の復習になりますから特に説明しません。
コピペコードファイルの「ラングオブジェクトを生成するメソッド」を登録して、「getAllメソッド(パスを配列で登録:’attributeArray’)」を実行します。
ちなみにラングオブジェクト生成の指定はつぎの様にしてます。上の掲載画像でラングオブジェクトの範囲を確認できます。
const range = newRange({start:{v:['post-transition','Sn'], b:false}, end:{v:['transition','Cu'], b:false}});

ちゃんと取得できました。それでは、マルチエントリーの紹介に移ります。
‘multiEntry’
マルチエントリーの対象は、インデックス(補キー)の値が配列である場合だけ有効です。
配列でなければ、普通のキーとして扱われる様子です。また、冒頭で「注意」したようにインデックス(補キー)のパスを配列で指定しようとすると例外が発生します。
マルチエントリーが真(ture)であれば「検索時に一つでも合致があれば対象とみなされるようになります。」と、どこか(忘却)にかいてありました。MDNでは「キーの配列の各要素それぞれをインデックスのレコードにします。」と説明してます。
少し難しいと思う方もおられるでしょうが、要は配列を全部開いてインデックス(補キー)にすると理解すれば良さそうです。
オブジェクトストアのインデックス(補キー)「tagMulti」の項目をアクティブにして確認すると、配列の要素数にインデックス(補キー)の値が増えているのがみて取れます。(どわっと。)

マルチエントリーが偽(false)であれば、配列は丸っとインデックス(補キー)の値になるだけです。確認まで、つぎは偽にした場合のキーの表示です。

視覚的に確認できるのはとても助かりますね。概ね、マルチエントリー指定の把握がすみました。
では、レコードの参照をしてみます。
状態が判っていれば、基本的には難しいことはありません。コピペコードファイルの「getAllメソッド(マルチエントリーを真指定で登録:’tagMulti’)」を実行します。
ちなみにラングオブジェクト生成の指定はつぎの様にしてます。
const range = newRange({start:{v:'jewelry', b:false}, end:{v:'jewelry', b:false}});

無事に、tag項目の配列内に’jewelry’という文字列があるレコードを取得できました。
後になって補足があるやもしれませんが、とりま、今回の投稿の目的を達成できたと思います。
次回からはカーソルを使ったインデックス(補キー)による操作を紹介します。遂にラスボスです。
マルチエントリーについては少々恐れていたのですが、インデックス(補キー)登録に制限があったため、それほどは難しくなくてほっとしました。夢でないことを祈ります。そかさ。