brief: | 1 i18n.site はサーバーレスの全文検索をサポートするようになりました。
2 i18n.site は、サーバーレスの全文検索をサポートするようになりました。
3 i18n.site は、サーバーレスの全文検索をサポートし、現在、純粋なフロントエンド全文検索を実装しています。
数週間の開発を経て、i18n.site(純粋な静的Markdown多言語翻訳およびサイト構築ツール)が、純粋なフロントエンドの全文検索をサポートするようになりました。
本稿では、i18n.site
の純粋なフロントエンド全文検索の技術的実装について詳述し、i18n.siteを訪れることで検索の効果を実感してください。
コードは以下の通りです:検索カーネル / インタラクティブインターフェース
ドキュメントや個人のブログなど、中小規模の純粋に静的な Web サイトの場合、独自に構築した全文検索バックエンドを構築するのは重すぎるため、サービス不要の全文検索がより一般的な選択肢となります。
11 サーバーレス全文検索ソリューションは大きく二つのカテゴリに分類されます
12 まず、algolia.comなどのサードパーティ検索サービスプロバイダーが、全文検索用のフロントエンドコンポーネントを提供しています。
13 このようなサービスは、検索ボリュームに応じて料金が発生し、ウェブサイトの規制やコンプライアンスの問題により、中国本土のユーザーが利用できないことが多いです。
14 オフラインでの使用やイントラネットでの使用ができず、大きな制限があります。この記事では特に詳しくは触れません。
15 次に、純粋なフロントエンドの全文検索があります。
現在一般的に用いられる純粋なフロントエンド全文検索には、lunrjsとElasticLunr.js(lunrjs
をベースに二次開発されたもの)があります。
lunrjs
のインデックス構築には二つの方法があり、それぞれに問題があります。
事前構築のインデックスファイル
19 文書が追加や変更されるたびに、新しいインデックスファイルをロードする必要があります。 20 これにより、ユーザーの待ち時間が長くなり、大量の帯域幅が消費されます。 21 ドキュメントをロードし、その場でインデックスを構築します。
ドキュメントをロードし、その場でインデックスを構築します
23 lunrjs以外にも、他の全文検索ソリューションがあります。
lunrjs
以外にも、以下のような他の全文検索ソリューションがあります:
fusejs 、検索する文字列間の類似性を計算します。
このソリューションのパフォーマンスは非常に低く、全文検索には使用できません (「 Fuse.js長いクエリには10秒以上かかります。最適化するには?」を参照)。
TinySearchは、ブルーム フィルターを使用して検索しますが、接頭辞検索 (たとえば、 goo
を入力し、 good
、 google
検索) には使用できず、同様の自動補完効果は得られません。
28 i18n.site
は、以下の特徴を持つ新しい純粋なフロントエンド全文検索ソリューションを提供しています
gzip
パッケージ化した後の検索カーネルのサイズは6.9KB
です (比較のために、 lunrjs
のサイズは25KB
です)indexedb
に基づいて転置インデックスを構築します。これはメモリの使用量が少なく、高速です以下に、技術実装のi18n.site
を詳しく紹介します。
36 ブラウザのネイティブなIntl.Segmenter
を使用して多言語の単語分割を行います。
単語分割coffeescript
コードは次のとおりです
SEG = new Intl.Segmenter 0, granularity: "word"
seg = (txt) =>
r = []
for {segment} from SEG.segment(txt)
for i from segment.split('.')
i = i.trim()
if i and !'|`'.includes(i) and !/\p{P}/u.test(i)
r.push i
r
export default seg
export segqy = (q) =>
seg q.toLocaleLowerCase()
で:
/\p{P}/
、句読点に一致する正規表現です。 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _
{ | } 〜。 。</p><ul><li>
split('.')は、
Firefoxブラウザの単語分割では
.`分割しないためです。
word
: id -
word
: id -doc
テーブルは、id、ドキュメントURL、およびバージョン番号を保存しますdocWord
テーブルは、ドキュメントIDとワードIDの配列を保存しますprefix
テーブルは、プレフィックスとワードIDの配列を保存しますrindex
テーブルは、ワードIDとドキュメントIDおよび行番号の配列を保存しますdocument url
とバージョン番号ver
の配列を渡し、テーブルdoc
にドキュメントが存在するかどうかを検索します。存在しない場合は、転置インデックスを作成します。同時に、渡されなかったドキュメントの逆索引を削除します。
49 存在しない場合は、転置インデックスを作成し、渡されなかったドキュメントの逆索引を削除します。
フロントエンド対話では、初回ロード時の遅延を避けるために、インデックスのロード進行状況バーを表示できます。「単一のprogress + Pure css実装に基づくアニメーション付きの進行状況バー」 English / Chinese を参照してください。
このプロジェクトは、 IndexedDBの非同期カプセル化に基づいてidb 。
53 競合書き込みによるデータの一部の損失を避けるためには、以下のCoffeeScriptコードを参照してください。
競合書き込みによる部分的なデータ損失を回避するには、以下のcoffeescript
コードを参照し、読み取りと書き込みの間にing
キャッシュを追加して競合書き込みを遮断します。
pusher = =>
ing = new Map()
(table, id, val)=>
id_set = ing.get(id)
if id_set
id_set.add val
return
id_set = new Set([val])
ing.set id, id_set
pre = await table.get(id)
li = pre?.li or []
loop
to_add = [...id_set]
li.push(...to_add)
await table.put({id,li})
for i from to_add
id_set.delete i
if not id_set.size
ing.delete id
break
return
rindexPush = pusher()
prefixPush = pusher()
60 検索では、まずユーザーが入力したキーワードをセグメント化します。
61 セグメント化された単語がN
であると仮定します。結果を返す場合、最初にすべてのキーワードを含む結果が返され、次にN-1
、N-2
、...、1
キーワードを含む結果が返されます。
62 最初に表示される検索結果によってクエリの正確さが保証され、その後読み込まれる結果(「さらに読み込む」ボタンをクリック)によって再現率が保証されます。
64 応答速度を向上させるために、検索ではyield
ジェネレーターを使用してオンデマンド読み込みを実装し、結果がクエリされるたびにlimit
結果を返します。
65 yield
後に再度検索するたびに、IndexedDB
のクエリトランザクションを再度開く必要があります。
ユーザーが入力中に検索結果を表示するため、たとえばwor
を入力すると、 words
やwork
など先頭にwor
が付く単語が表示されます。
68 検索カーネルは、単語の分割後の最後の単語に対してprefix
テーブルを使用して、その接頭辞が付くすべての単語を検索し、順番に検索します。
手ぶれ補正機能debounce
は、検索をトリガーするユーザー入力の頻度を減らし、計算量を減らすために、フロントエンド インタラクション (次のように実装) でも使用されます。
export default (wait, func) => {
var timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(func.bind(this, ...args), wait);
};
}
インデックス テーブルには元のテキストは保存されず、単語のみが保存されるため、ストレージの量が削減されます。
72 同時に、service worker
がすべての記事をキャッシュするため、ユーザーが検索を実行すると、検索を含むウェブサイト全体がオフラインで利用できるようになります。
i18n.site
の純粋なフロントエンド検索ソリューションは、Markdownドキュメントに特化しています。
i18n.site
の純粋なフロントエンド検索ソリューションは、 MarkDown
ドキュメント用に最適化されています。
要約
逆引き全文検索は純粋にフロントエンドに実装されており、サーバーは必要ありません。ドキュメントや個人のブログなどの中小規模の Web サイトに非常に適しています。
i18n.site
オープンソースの自社開発の純粋なフロントエンド検索は、サイズが小さく応答が速く、現在の純粋なフロントエンド全文検索の欠点を解決し、より良いユーザー エクスペリエンスを提供します。