end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

sqlite fts4 + sql.js によるブラウザでの全文検索

sql.jsは sqlitejavascript + web assembly版ですので、 先程のentryの続きとして、ブラウザでの全文検索を行います。

参考url

sql.js v.1.10.2 は fts5 未対応 → fts4 を使用

現時点で sqlite の ftsは fts5 ですが、 sql.js v.1.10.2 で fts5 で作成した sqlite データを読むと、 エラーとなりましたので、fts4 を使用します

step1 - sqlite データ (*.db)を作成

以下の通り。

ただし、N-gram (bigram)処理は、 先程のentryのように実施した方がよいかも

CREATE VIRTUAL TABLE
            IF NOT EXISTS fts USING fts4(
            file,
            date,
            text,
            tokenize=unicode61,
            notindexed=file,
            notindexed=date
            );

insert into fts values('今日は','晴天','かもしれません');
insert into fts values('明日は','雨天','のはずです');

SELECT * FROM fts WHERE fts MATCH ('*のはず*');
SELECT * FROM fts WHERE fts MATCH ('のはずです');

step2 - sql.js で sqlite fts4 データから全文検索

<meta charset="utf8" />
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.2/sql-wasm.js">
</script>
<script>
  async function init_sqljs() {
      const sqlPromise = initSqlJs({
          locateFile:file=>`https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.2/${file}`
      });
      
      const dataPromise = fetch("fts.db").then(res => res.arrayBuffer());
      const [SQL, buf] = await Promise.all([sqlPromise, dataPromise])
      const db = new SQL.Database(new Uint8Array(buf));

      let sql = `
  SELECT * FROM fts WHERE fts MATCH ('*のはず*')
`;
      const stmt = db.prepare(sql);
      //stmt.bind(;
      //console.log( stmt );
      
      let sql_result = "";
      while( stmt.step() ) {
          let row = stmt.getAsObject();
          sql_result += JSON.stringify(row);
      }
      document.querySelector("#sql_result").innerHTML = sql_result;
      
      stmt.free();
      //const dbBinary = db.export();
      db.close();
  }
  
  init_sqljs();
</script>
<body>
  <div id="sql_result"></div>
</body>
</html>