はじめに
FAQを内製するとき、最初に決めるべきは「データをどう持つか」です。
ここを軽く作れるかどうかで、その後の運用のしやすさが大きく変わってきます。
この記事では、私がアパレル・ギア系のECサイトで採用した、カテゴリ別JSON+Vercel KVという構成と、横断検索を支える検索インデックスの作り方を解説します。データベースをがっちり組むほどでもないけれど、ただのテキストでは検索が弱い。その間をうまく取る設計です。
カテゴリ別JSONというデータの持ち方
1カテゴリ1ファイルに分ける
FAQは約10カテゴリ・100問超あります。これを1つの巨大なファイルにまとめると、編集のたびに全体を触ることになり、差分も見づらくなります。そこで、カテゴリごとに1つのJSONファイルへ分割しました。「送料・配送」「返品・交換」「会員登録」といった単位です。カテゴリを追加したいときは新しいファイルを足すだけ。編集の影響範囲がファイル単位で閉じるので、複数人で触っても衝突しにくいのが利点です。
1問を表す最小の構造
1つのFAQは、質問・回答・並び順といった最小限のフィールドで表します。凝ったスキーマにせず、あえてシンプルに保つのがポイントです。回答には簡単なリンクや装飾を許容しつつ、構造そのものは平らにしておくと、管理画面からの編集もGit上での差分確認も素直になります。
なぜ最初はJSONで十分なのか
「FAQくらいでデータベースは大げさ」というのが正直なところです。件数は数百件規模で、更新頻度もそれほど高くありません。JSONならGitでそのままバージョン管理でき、いつ・誰が・どこを変えたかが履歴に残ります。リレーショナルDBのようなスキーマ移行の手間もなく、まずはこれで十分に回ります。
Vercel KVとの同期で配信を速くする
「正」はJSON、配信はKV
JSONは管理には向きますが、リクエストのたびにファイルを読んで解析するのは配信としては非効率です。そこで、JSONを「正(source of truth)」として持ちつつ、本番の表示は高速なキーバリューストア(Vercel KV)から引く二段構えにしました。JSONを更新したら同期してKVへ反映し、ユーザーが見るのは常にKV上のデータです。管理のしやすさと表示の速さを、どちらも諦めずに済みます。
カテゴリ単位でキーを設計する
KVにはカテゴリ単位でデータを載せています。カテゴリページを開いたときに、そのカテゴリのFAQだけを一発で引ければ十分だからです。全FAQを毎回まとめて読む必要はなく、必要な分だけを取り出せるので無駄がありません。
Gitで管理された「正」のデータを更新
push処理でVercel KVへ反映
全カテゴリを横断できる索引を作り直す
カテゴリページとインライン検索が最新データを表示
横断検索を支える検索インデックス
カテゴリをまたいで探せるようにする
FAQをカテゴリ別に分けると管理はしやすいのですが、ユーザーは自分の疑問がどのカテゴリに属するか分かりません。「返金」で調べたいのに、それが「返品・交換」なのか「支払い」なのか迷ってしまう。そこで、全カテゴリのFAQをまとめた**検索用インデックス(search-index)**を別途生成し、カテゴリをまたいだ横断検索を可能にしました。ユーザーはカテゴリを意識せず、言葉だけで探せます。
軽い前処理で当たりを良くする
検索インデックスは、質問文と回答本文をまとめて索引化します。あわせて、表記ゆれを吸収する軽い正規化(全角半角の統一など)をかけておくと、検索の当たりが良くなります。凝った全文検索エンジンを立てなくても、この程度の前処理で「打った言葉が拾える」体験は十分に作れます。インデックス自体もKVに載せ、入力に応じてインラインで候補を返します。
重いエンジンは必要ない
数百件規模のFAQなら、専用の全文検索エンジンを導入しなくても、事前生成した検索インデックス+軽い正規化で実用十分です。まずは小さく作り、件数が増えて困ったら強化する、という順番が現実的です。
まとめ
FAQのデータ設計は、カテゴリ別JSONを「正」として持ち、配信はVercel KVから、横断検索は事前生成した検索インデックスから、という三点で構成しました。データベースを組むほどではないけれど、ただのテキストよりは賢い。その塩梅が、数百件規模のFAQにはちょうど良いんです。
このデータをどう編集・同期して運用するかは、管理画面編集とGit経由の同期運用で解説します。全体像はFAQシステムの内製をご覧ください。