フィルタリングと全文検索
1)検索レイヤーが必要な理由
フィルタリングと全文検索(FTS)は、主キーだけでなく「意味による」データへの迅速なアクセスを提供します。適切に設計された検索レイヤーが組み合わされます:- 厳密なフィルター(カテゴリ、日付、価格、アクセス権)
- 全文(語彙マッチとランキング)
- ファセット(ナビゲーションの集計)
- ハイブリッドランキング(BM25/TF-IDF+ベクトル埋め込み)
- 信頼できるプロトコル(カーソルページネーション、トークンTTL、クロスシャーディング)
2)建築絵
コンポーネント:1.Ingest/ETL→normalization、重複排除、enrichment、 indexの構築フィールド。
2.インデックス→リバースインデックス(トークン→ドキュメント)、カラム構造、ベクターインデックス(HNSW/IVF-PQ)。
3.クエリーレイヤー→リクエストパーサ、フィルタ/アクセス権の適用、シャードスケジューラ、k-wayマージ。
4.ランカー→BM25+LTR/神経再ランク。
5.サービング→キャッシュ、カーソル、ファセット、ハイライト、オートコンプリート。
6.観測性→レイテンシー、品質指標、A/B実験。
3)データとインデックスモデル
3.1フィールドとアナライザ
型:キーワード(一致しても)、テキスト(分析)、数値/日付/ジオベクトル。
アナライザ:トークン化、正規化(小文字、Unicode NFKC)、フィルタ(stopwords、 stemming/lemmatization)。
多言語:フィールドアナライザ(ru、 uk、 en);ICU分析;transliteration;diacriticsの考察。
3.2リバースインデックス(スパース)
構造:用語→投稿リスト(docID、 term freq、 positions)。
ランキング:フィールドブースト付きBM25(またはクラシックTF -IDF)。
3.3ベクトルインデックス(高密度)
テキスト埋め込み(例:384-1024-dimensional)。
ANN構造:HNSW、 IVF-PQ、フラット(小型セット用)。
Cosineの近接/内部プロダクト;BM25校正(ハイブリッド)
3.4ファセットと集計
速いカウントのための値のPrecompute/columnの貯蔵。
階層ファセット(category/subcategory)。
範囲(価格ビン、日付)。
4)クエリ: フィルタ+全文+並べ替え
4.1 API契約(REST)
リクエスト:
GET /v1/search? q = classic slots & limit = 20 & cursor =... & sort = score: desc, created _ at: desc
&filters=brand:("NetEnt","EGT"); price:[10 TO 50];published_at:[2024-01-01 TO ]
&facets=brand,year,price:range(0,10,20,50,100)
応答(フラグメント):
json
{
"items": [ { "id":"...", "title":"...", "score": 12. 3, "highlight": { "content": ["..."] } } ],
"facets": { "brand": [{"value":"NetEnt","count":123},...] },
"page": { "limit":20, "has_more":true, "next_cursor":"opaque-token" }
}
4.2 GraphQL(簡略化)
graphql type Query {
search(query: String!, filter: SearchFilter, first: Int, after: String, sort: [Sort!]): SearchConnection!
}
4.3 gRPC
proto message SearchRequest {
string query = 1;
map<string,string> filters = 2;
int32 page_size = 3;
string page_token = 4; // курсор repeated string facets = 5;
}
5)自然言語処理(NLP)
トークン化/正規化:Unicode-safe、ハイフン/アポストロフィ会計。
Stopwords:言語によるカスタマイズリスト。
Stemming vs lemmatization: ru/uk lemmatizationの方が良い(quality> speed)。
同義語:双方向/方向辞書;TTLを使用した辞書のバージョン。
Typos(ファジー):距離制限と正確なマッチブーストを持つDamerau-Levenshtein。
N-grams/edge-ngrams:オートコンプリートとヒント用。
翻訳:「shch ↔」 「u」「、kyiv/kyiv」-対応ルール。
6)関連性とランキング
6.1基本的な辞書のスコア
コレクションによる'k1'、 'b'の設定でBM25します。
フィールドごとにブーストします(title^3、 tags^1。5、 body^1)。
鮮度:'score+=freshness_boost (decay (created_at))'。
6.2行動の手掛かり
クリックスルー率、ドウェル時間、お気に入りに保存(反位置バヤと)。
重複排除-~の同一コンテンツ(MinHash/SimHash)でドキュメントをステッチします。
6.3ラーニング・ツー・ランク(LTR)
特徴:フィールドBM25、長さ、新鮮さ、人気、フレーズによるマッチ、位置速度。
モデル:LambdaMART/XGBoost;オフラインメトリクスNDCG@k、 MAP、 Precision@k;オンラインA/B。
6.4神経再配置
2ステップ:recall (BM25/ANN)→top-N(例:200)→クロスエンコーダのランク。
費用の会計:時間の予算、負荷の下で神経段階なしのフォールバック。
6.5ハイブリッド検索(sparse+dense)
融合(速度と合計の正規化)、またはマルチステージ(ランクとして密度)のいずれか。
校正は重要です:min-max/z-score/quantitative mapping。
7)フィルタリング、ファセットおよびアクセス
7.1フィルター
演算子:'='、'IN'、範囲、接頭辞、ジオバウンディングボックス/ジオディスタンス。
組み合わせ:フィルタによる'AND'、値のセット内の'OR' (brand IN……)。
Type security:数値フィールドはテキストとして解析されません。
7.2ファセット
事前に計算された構造のための安いカウント。
「Applied」ファセットには、残りのポストフィルターファセットが表示されます。
7.3アクセス/マルチテナンシー
セキュリティフィルタはランキング前に統合されています(プレフィルター)。
ドキュメント内のABAC/RBACフィールド('tenant_id'、 'visibility'、 'acl')。
リクエストトークンは署名されます。マルチテナント-自動'tenant_id'フィルター。
8)ページネーション、カーソル、一貫性
シークカーソルによるページネーション'(スコア、タイブレーカー)'または'(created_at、 id)'で時間順にソートします。
HMACとTTLで不透明な'page_token'。
整合性:ニアリアルタイム(NRT)インデックス:遅延0。記録と可視性の間の5-2 s。SLAに文書化します。
クロスシャード:ローカル検索→グローバル注文によるk-wayマージ、トークン内のシャードカーソルごと。
9) AutoCompleteおよびプロンプト
提案:prefix-trie/edge-ngrams полю 'title'。
人気のクエリ:クリックのログ→人気のヒント+パーソナライゼーション(セグメント)。
Spell-as-you-type:距離制限'<=1'の高速ファジー検索。
GET /v1/suggest? q=kaz&limit=8&locale=ru
→ ["casino," "casual games,..."]
10)ハイライトとスニペット
位置インデックス→マッチしたフレーズを取得します。
HTMLエスケープ、長さ制限、隣接するフラグメントの結合。
関連する用語の密度によるスニペットのランキング。
11)パフォーマンス、キャッシュ、SLO
インデックス:メモリ内のホットセグメント;圧縮の投稿;facetsのdoc値。
キャッシュ:L1(プロセス)、L2 (Redis)、ファセット/集計キャッシュ;インデックスバージョンで無効化されています。
SLO: 'k<=20'でのP95 <150-200ミリ秒、P99 <500ミリ秒;可用性99。9%.
Backpressure: 'k'を減らし、オーバーロード時にニューロステージを無効にします。
API/user/tenantキーへのレート制限。
12)観測可能性と品質指標
テクニカルメトリクス:- 'search_latency_ms' (P50/P95/P99)、' qps'、'timeouts'、 'error_rate'
- 'cache_hit_ratio'、 'facet_cache_hit'、 'rerank_share'
- 'shard_fanout'、 'merge_time_ms'、' ann_recall@k'
- NDCG@k、 MAP、 MRR、 Recall@k、 Precision@kのマーク付きサンプル。
- CTR@k、 sCTR(満足したクリック)、ドウェル時間、ぽっちゃり率。
A/B:「ガードレール」メトリック(レイテンシ、エラー)+ターゲット(NDCGプロキシ)を修正しました。
13)テスト
Relevance unit tests:キーリクエストの予想される一致をチェックします。
プロパティベース:typos/synonyms/languagesに対する抵抗。
ページネーション:ページ境界(シークコントラクト)に重複はありません。
セキュリティ:アクセスフィルタは常に適用されます(faset-countでも)。
辞書の回帰:バージョン管理の同義語とファジールール。
14)セキュリティとプライバシー
PIIを持つフィールドはテキストとしてインデックスされません。別々に/暗号化を保存します。
保存されたソースを最小限に抑えます(store=false、スニペットフィールドのみ)。
クエリのプライバシー:PIIで生のリクエストをログに記録しないでください。匿名化/ハッシュ化。
マルチテナント:厳密なインデックス分離または必須の'tenant_id'フィルター。
15)移行と相互運用性
二重書き込みと漸進的なスイッチでインデックススキーム(v1→v2)をバージョン管理します。
Analyzerの互換性:古いチェーンはまだ再インデックスしないでください。
同義語/ストップワード辞書の回転:'version'、 'activated_at'、ロールバック。
16)実用的なレシピ
16.1古典的な語彙検索(BM25)
フィールド:'title^3'、 'tags^2'、 'body^1'。
アナライザ:言語固有の+lemmatization。
短いクエリのファジー('<=3'トークン)、'fuzziness=1'。
16.2ハイブリッドスパース+密
1.クエリ埋め込みによるANN検索(k=200)
2.トップ200 BM25とのマージ
3.キャリブレーションランクフュージョン
4.Take top-N (N=20)、オプションで-十分な予算を持つランクのクロスエンコーダ。
16.3ファセットカタログナビゲーション
権利/テナントによるハードプリフィルタ
ポストフィルターファセット(アクティブなフィルタを含むカウント)
関連性またはビジネス分野(価格/新規性)で並べ替え)
17)サンプルリクエスト(擬似DSL)
フィルタと並べ替え:json
{
"query": "live casino,"
"filters": {
"country": ["EE","LV","LT"],
"license": ["MGA","UKGC"],
"launched_at": {"gte": "2023-01-01"}
},
"sort": ["_score:desc","launched_at:desc"],
"facets": ["country","license"],
"page": {"limit": 20, "cursor": "opaque"}
}
Geopoisk:
json
{
"query": "casino",
"geo": {"lat": 59. 437, "lon": 24. 753, "radius_km": 50}
}
オートコンプリート:
json
{ "prefix": "evo", "field": "brand_suggest", "limit": 8 }
18) UXパターン
アクティブフィルターチップ+「すべてリセット」。
空白の結果:show 「try……」(同義語、フィルタを削除)。
ゼロヒント:人気のあるクエリ/カテゴリ。
カーソルページネーション(その他のボタン)と無限スクロール;適用されたフィルターの固定指標。
別のスイッチ「アカウントのタイプスを取る」、「フレーズの正確な一致」。
19)頻繁なエラーとアンチパターン
ソート→ダブル/ジャンプ時のタイブレーカなし。
アクティブフィルタ→「false」カウントを考慮しないファセット。
ランキング後のアクセスフィルタを適用します。
異なる言語と1つのアナライザを混在させます。
seekカーソルではなくDeep pagination OFFSET/LIMIT。
無制限のファジー→レイテンシーによる爆発。
20)実装チェックリスト
1.フィールドとそのタイプを定義し、ロケールアナライザごとに割り当てます。
2.inverse index+を設計します(オプション)。ベクトルANN。
3.クエリパーサとセキュアプリフィルタを実装します。
4.BM25とフィールドのブーストを設定します。ファセットを取り付けます。
5.カーソル(不透明、HMAC、 TTL)とk-wayマージをシャードで入力します。
6.オートコンプリート、ハイライト、安全なシールドを追加します。
7.メトリクス:レイテンシ、NDCG@k、 CTR;キャッシュをL1/L2します。
8.関連性を調整するためのA/Bフレームワーク。
9.文書SLA: NRT遅延、「制限」制限、一貫性の保証。
10.移行計画:インデックス、辞書、アナライザのバージョン。
よく設計されたフィルタリングと全文検索レイヤーは、高速なインデックスだけでなく、カーソル、セキュリティ、予測可能なUX、および測定可能な関連性を持つ明確なプロトコル契約でもあります。このアプローチは数千から数十億のドキュメントに拡張され、古典的な語彙検索とニューラルネットワークのランキングを持つ現代のハイブリッドシナリオの両方をサポートします。