Fuse.jsで誤字に強い図書検索:完全一致とあいまい検索を比較

プログラミング・Web開発カテゴリを表すパンダのイラスト プログラミング・Web開発

この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。Fuse.js公式の検索オプションと、GitHubに保存済みの架空の図書5件のコードを照合しました。タイトル完全一致と、文字列の一部・誤記を許す候補検索を区別します。実ブラウザでの動作は未確認です。

検証ステータス: 2026-10-30までの既存審査で、公式資料と保存済みDaily Codeの固定ソースを照合し、Node.js構文検査の結果を記録しています。ブラウザ実操作、描画、CDN応答は未検証です。画面の説明はコードからの期待値であり実測と区別します。

項目内容
対象Chrome/Edge/Firefox等の現代的なブラウザ(実機互換性は未確認)
使用ライブラリFuse.js(教材内バージョン: 7.5.0)
費用デモのソース自体に有料APIは不要。通信料金や利用条件は環境に依存
データページ内の架空データ。認証情報・位置情報・企業データ不要
学習操作本のタイトルを検索し、近い候補の順位を見る

なぜこの技術を試すのか

表記が少し違うだけで検索が0件になると、利用者は登録されている情報にたどり着けません。Fuse.jsはクライアント側であいまい検索を行うJavaScriptライブラリです。図書のタイトル、読み方、ジャンルなど小規模なデータの候補探しに向きます。今回の図書データは架空の五件だけです。検索窓へ一部の文字を入れたときに何が候補になるか、完全一致検索と何が違うかを観察します。検索で候補を見つけることと、その候補が正しい対象であることは分けて考えます。

動くサンプルを作るときは、見た目が動いたという事実だけで終わらず、「どの入力がどの変数を変え、どの処理が描画を更新したか」を区別する必要があります。今回の教材では、その変化を画面に明示します。実際のサービスへ取り込むときには、認証や保存の処理を別途設計してください。

まず試す:正しいファイルと操作手順

この教材のREADMEは web/fusejs-book-search/README.md、実行ファイルは別の docs/demos/fusejs-book-search/ にあります。同じフォルダだと思ってREADME側から index.html を探すと見つかりません。2026-10-28に照合済みの固定コミットを参照してください。

PCで動かす(公開デモに依存しない)

  1. 上記の index.html と app.js を同じ新規フォルダへ保存します。GitHubのHTML表示をそのまま保存せず、各ファイルのRaw表示からテキストを保存します。

  2. そのフォルダでターミナルを開き、Python 3があるか確認します。Windowsは py -3 --version、Linux/macOSは python3 --version。Pythonがなければ無理にインストールせず、既存の開発環境で静的ファイルを配信できる方法を選んでください。

  3. Windowsは py -3 -m http.server 8000 --bind 127.0.0.1、Linux/macOSは python3 -m http.server 8000 --bind 127.0.0.1 を実行します。ローカル端末だけからアクセスする指定です。

  4. ブラウザで http://127.0.0.1:8000/ を開きます。起動したターミナルは閉じず、終了時に Ctrl+C を押します。会社のPCで外部CDNが禁止されている場合は実行を中止し、規程を確認してください。

期待される画面:検索欄の初期値は JavaScrip、しきい値スライダーは 0.3、検索結果は <ul> に並び、下の状態表示は SUCCESS: ○件 / 閾値 0.3 となります。件数や順位は実ブラウザで未測定です。状態表示がSUCCESSでも、実際に候補名が見えることを別途確認してください。

完全一致と「あいまい」の違いを観察する

図書データには JavaScript入門、マンガの描き方、ジャバスクリプト実験、地図を作る、図解Web技術 の5件が入っています。

  • タイトル全体の完全一致:book.title === 'JavaScrip' なら一致は0件です。これは5件の文字列をコード上で比較した確定結果で、Fuse.jsの結果ではありません。

  • Fuse.jsの候補検索:検索欄の JavaScrip に対し、JavaScript入門 が候補になるか、実際のブラウザで確認してください。先頭からの部分一致や文字の欠落を扱えますが、しきい値や位置の設定で結果は変わります。

  • スライダーを0へ:threshold: 0 はタイトル全体の完全一致モードではありません。検索語がタイトルの先頭などにそのまま含まれる場合、タイトル全体が異なってもヒットし得ます。タイトルの厳密な識別には === や固有ID照合を使います。

  • 検索欄を空に:実装は検索せず5件を一覧表示します。コード上の期待値は SUCCESS: 5件 / 閾値 0.3(スライダーを戻した場合)です。

  • 日本語の読み違い:ローマ字の JavaScript とカタカナの ジャバスクリプト を自動的に同一視する機能ではありません。

開発者ツールのConsoleに Fuse is not defined が出たらCDNの読み込み順や通信を、404なら app.js の保存場所を確認します。表示が空でもConsoleが正常なら、入力文字列としきい値を一つずつ戻します。結果の多さより、利用者が誤選択しないことを重視します。

仕組みの全体図

flowchart LR
    A["入力やクリック"] --> B["イベントを受ける"]
    B --> C["Fuse.js のAPI"]
    C --> D["状態と描画を更新"]
    D --> E["見た目と文字で確認"]

この図は学習用の概念図で、ブラウザ内部の実装やネットワーク通信の詳細を表したものではありません。ライブラリが何でも「操作がどの変数へ届くか」を追いかけることは共通です。

どう動いているのか:APIを読み解く

Fuseへ渡す配列は検索対象、keys は照合するフィールドです。threshold は候補を許容する厳しさを調整し、0に近いほど厳しくなります。includeScore で取得する score は小さいほど近い評価値ですが、正解確率でも単純な編集距離でもありません。実際のサンプル画面では便宜上「距離」と表示していますが、正確にはFuse.jsのスコアです。このラベルはDaily Code側の今後の表示改善対象です。利用者が候補名を確認せず自動確定する用途には使いません。詳しくは公式Fuzzy Searchのthreshold・location・distanceとGetting Startedのスコア説明を参照してください。

最小コードの読み方

const fuse = new Fuse(books, { keys: ["title"], includeScore: true, threshold: 0.3 });
const results = fuse.search("JavaScrip");
// scoreは正解の確率ではない

上記はAPIの要点を取り出した抜粋です。コピーして単独実行する完成ファイルではありません。動かすためのHTMLと実装一式はDaily Code側のREADME/デモファイルで確認してください。どの関数がHTML要素を選び、どの行が数値を更新するかを追い、既知の架空値で試します。

一条件だけ変更して比較する

このデモで実際に変更できるのは検索文字列とthresholdのスライダーです。まず JavaScrip を入力したまま、スライダーを 0.3 → 0 → 0.7 → 0.3 の順に動かします。各段階で SUCCESS: ○件 / 閾値 ○ と候補名・順位を記録してください。件数の実測は未実施なので、増減を保証する表は掲載しません。候補が変わらない場合も、短い検索語が文字列の先頭と一致している可能性があります。

実装を発展させるなら keys: ['title'] に author や genre を追加できます。ただし現行の5件にはそのフィールドがありません。単にkeysを増やしても検索対象データが存在しなければ比較にならないため、フィールド追加は別実験として扱います。完全一致との違いを検証する場合は books.filter(b => b.title === query) の件数と、Fuse.jsの search(query) の件数を別々に比較します。

失敗したときにどこを見るか

日本語の全角半角、カタカナとひらがな、漢字の読み、濁音と清音は、単純なあいまい一致だけでは吸収しきれません。必要ならデータ側へ読み仮名や別名を持たせ、正規化したフィールドを別途用意します。さらに検索対象が数十万件へ増えると、全データをブラウザへ渡す方式が重くなり、権限のない人へ情報を渡してしまう危険もあります。サーバー検索へ切り替える境界を決めてください。

観察した状態切り分ける点対応の例
画面が初期状態から変わらないスクリプト取得・初期化・イベント登録Console / Network / scriptタグを確認
表示が変わるが意味が合わない入力値・配列・単位・更新対象値を固定して一条件ずつ確認
検索欄・スライダーを動かしても変わらない#q/#v のinputイベント、スクリプト取得Consoleのエラー、HTMLのid、app.jsの読み込み順を確認
一部の端末だけ動かないブラウザ機能、権限、CDN、性能端末とバージョン、再現操作を記録

ブラウザ内でのエラーと公開Webサーバーの障害は別です。前者は開発者ツールのエラー内容、後者はHTTPレスポンスやアセットの配信条件から調べます。未知の失敗を成功と表現しないことが、技術メモの信頼性を高めます。

業務・学習への応用

社内用語集、部品名の候補表示、イベント名検索、FAQナビゲーションなどに使えます。ただし医薬品名や決済相手の選択など、誤選択の影響が大きい用途は候補表示と確定操作を分け、正式な識別子による照合が必要です。検索を便利にしても、識別や承認の責任を検索ライブラリへ任せないことが重要です。

導入前に決めること

読者へ公開するとき、表示したデータがどこから来るか、誰が変更できるか、画面へ残る情報の種類、ライブラリ更新時の確認項目を決めます。今回のデモにはログインもサーバー保存もありません。そこで運用機能を追加する前に、まず「想定どおり表示される最小部分」と「実務上の信頼性・権限・バックアップが必要な部分」を区別することを勧めます。第三者CDNは外部通信のため、企業ネットワークで許されるか事前確認が必要です。

別方式と比較する

方式向く場面注意点
Fuse.js本のタイトルを検索し、近い候補の順位を見るなど目的に合う場面依存ライブラリの更新・利用条件の管理が必要
ブラウザ標準API小さな機能を自前で作る仕様や互換性を自分で確認する
静的画像・表操作を必要としない説明状態の変化をその場で体験できない

ライブラリは必要なときに選ぶ道具です。何を達成したいかと学習コストを合わせて比較します。「ライブラリを入れること」を目的にしない方が、小規模なページでは保守しやすくなります。

GitHubサンプル

ブログ本文は背景や考え方、Daily Codeは実行・改造するためのコード、という役割を分けています。外部サービスへ投稿・保存するAPIは含めません。

公式情報・一次情報

資料確認範囲: 2026-10-30に公式Getting StartedとFuzzy Searchを再確認。旧 /api/options.html は404だったため、現行ページへ修正しました。CDNの実通信・ブラウザ描画は確認していません。

検証範囲の補足

Daily Codeの固定コミットと既存のNode.js構文検査結果を参照できます。ただし実ブラウザの画面表示、ライブラリCDNの応答、全端末での動作は未確認です。実際の動作は読者の環境でConsoleとNetworkを利用して確かめてください。

文書情報

記事タイトル
Fuse.jsで誤字に強い図書検索:完全一致とあいまい検索を比較
作成日
更新日
Source URL
https://papanda925.com/?p=18285

ライセンス: 本記事のうち、当サイトが権利を有する本文・自作図表は、特記なき限り CC BY 4.0 で利用できます。生成AIを活用して作成・編集した内容を含みます。コードについて、別途ライセンス表示またはリンク先GitHubリポジトリのライセンスがある場合は、その条件を優先します。引用・第三者資料・画像・商標等は本ライセンスの対象外です。 利用ポリシー

タイトルとURLをコピーしました