GH GambleHub

テクノロジーとインフラ→Elasticsearchと全文検索

Elasticsearchと全文検索

1) Elasticsearchの役割

Elasticsearch (ES)は、反転インデックスと集計のためのカラム構造に基づいた分散検索および分析システムです。それは与えます:
  • 全文:関連性(BM25)、形態、ファジー/タイプトレラント。
  • ファセットと集計:属性によるクイックスライス。
  • ハイブリッド検索:BM25+ベクトルkNN(セマンティクス)。
  • 開発スピード:クエリDSL、インジェストパイプライン、豊富なエコシステム。

iGaming/fintechの場合:ゲーム/プロバイダ、プロモーションとルールの検索、高速反応ファセット(プロバイダ、ボラティリティ、RTP、言語)、KYC/AML雑誌の検索、ログとアラートの解析。


2)データモデルとマッピング

2.1フィールドインデックスとタイプ

'date'、 'long/double'、 'boolean'、 'ip'、 'geo_point'

'text'を使用します。
'キーワード'-正確な値/集計/並べ替え。
'nested'-正しいフィールド相関を持つオブジェクトの配列。
'dense_vector'-ベクトル表現(埋め込み)。

2.2マルチフィールド戦略

フィールドを複数のビューに保存します:'name。text'、'name。raw'(キーワード)、'name。ngram'(自動補完用)。

json
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ru_morph",
"fields": {
"raw": { "type": "keyword", "ignore_above": 256 },
"ngram": { "type": "text", "analyzer": "edge_ngram_2_20" }
}
},
"provider": { "type": "keyword" },
"tags":   { "type": "keyword" },
"rtp":   { "type": "float" },
"released_at": { "type": "date" },
"lang":   { "type": "keyword" },
"embedding": { "type": "dense_vector", "dims": 384, "index": true, "similarity": "cosine" }
}
},
"settings": {
"analysis": {
"filter": {
"ru_stop": { "type": "stop", "stopwords": "_russian_" },
"ru_stemmer": { "type": "stemmer", "language": "russian" },
"syn_ru": { "type": "synonym", "lenient": true, "synonyms": [
"слот,игровой автомат => слот",
"джекпот,суперприз => джекпот"
] }
},
"analyzer": {
"ru_morph": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "ru_stop", "ru_stemmer", "syn_ru"]
},
"edge_ngram_2_20": {
"type": "custom",
"tokenizer": "edge_ngram",
"filter": ["lowercase"],
"char_filter": [],
"tokenizer": "edge_ngram"
}
},
"tokenizer": {
"edge_ngram": { "type": "edge_ngram", "min_gram": 2, "max_gram": 20 }
}
}
}
}

2.3ファセットのネスト

フォーム'featuresの属性:[{name、 value}]' design 'nested'、そうでなければfacetsはfalse matchを与える。


3)関連性: BM25、ブースト、ハイブリッド

3.1古典(BM25)

重みを持つフィールドを組み合わせます(タイトル^4、タグ^2、説明)。
ノイズの多いマッチを制御するには、'minimum_should_match'を使用します。

3.2ベクトル(kNN)+BM25 (rerank)

埋め込み(例:'dense_vector'の384-768)。
ベクトルによる最初のkNN(トップ200-500)、その後、BM25+ビジネスのブーストを再調整(ノベルティ、RTP、リージョンライセンス)。

ハイブリッドクエリの例:
json
{
"knn": {
"field": "embedding",
"query_vector": [/... /],
"k": 400, "num_candidates": 2000
},
"query": {
"bool": {
"should": [
{ "multi_match": {
"query": "египетские слоты джекпот",
"fields": ["title^4","tags^2","description"],
"type": "best_fields",
"minimum_should_match": "60%"
}}
],
"filter": [
{ "term": { "region": "TR" }},
{ "range": { "rtp": { "gte": 94.0 }}}
]
}
},
"rescore": {
"window_size": 400,
"query": {
"rescore_query": {
"function_score": {
"query": { "match_all": {} },
"boost_mode": "sum",
"functions": [
{ "gauss": { "released_at": { "scale": "180d", "offset": "30d", "decay": 0.5 } } },
{ "field_value_factor": { "field": "popularity", "factor": 0.2, "modifier": "log1p" } }
]
}
}
}
},
"highlight": { "fields": { "title": {}, "description": {} } }
}

4)自動補完およびプロンプト

アプローチ:
  • サブフィールドのタイトルのEdge N-gram。ngram'(高速、シンプル)。
  • 補完候補('completion'フィールド)-クイックヒントですが、個別のインデックスパスです。
  • Search-as-you-type-トークン化を組み合わせて単語やフレーズを開始します。
サンプルプロンプト:
json
{ "suggest": { "game-suggest": { "prefix": "book o", "completion": { "field": "title_suggest", "fuzzy": { "fuzziness": 1 }}}}}

5)同義語、タイプミス、多言語主義

同義語:'synonym'フィルタを使用してファイル/リストをロードします。別のドメイン(カジノ/スポーツ)。
Typos: 'multi_match'の'fuzziness: AUTO'、長さとフィールドの制限。プロンプト-'fuzzy'補完モード。

多言語主義:
  • Index-per-locale (ru/en/tr/pt-BR)またはマルチアナライザ回路:'title_ru'、 'title_en'。
  • analyzers: 'russian'、 'english'、 'turkish'、 'portuguese'。
  • 言語をルーティングキーに移動して、ホットロケールをユーザーに近づけるようにします。

6)フィルター、ファセットおよび集計

ファセットの場合は、'keyword'と'nested'集計を使用します。
集計中の枢機卿フィールド(一意のID)を避けます-それらを'runtime fields'またはpre-windowに持ち込みます。

ファセットの例:
json
{
"size": 20,
"aggs": {
"by_provider": { "terms": { "field": "provider", "size": 20 } },
"by_volatility": { "terms": { "field": "volatility" } },
"rtp_hist": { "histogram": { "field": "rtp", "interval": 1 } }
}
}

7)データ入力とテキスト消去

インジェストパイプライン:正規化、フィールド抽出、ジオエンコード、HTML削除。
添付ファイル/ingest-ocr(必要に応じて):PDF/画像インデックス(PIIに注意)。
Lemmatization:アナライザまたは外部パイプラインを介して(プリコンピューティングトークン)。


8)シャード、レプリカ、ILM

8.1次元およびシャーディング

より少ない破片はよりよいです。ターゲット:混合された負荷のためのシャードごとの10-50GB。
'number_of_shards: 1-3'から始めて、実際にスケールします。レプリカ-売上高で少なくとも1。

8.2 ILM(ライフサイクル)

ログ/履歴プロモーションのためのhot→warm→cold→delete。
コールドセグメントの強制マージ。
カタログや製品検索の場合-定期的な最適化で「永続的」ホット。

8.3ダウンタイムフリー移行アルゴリズム

新しいインデックス'games_v2'→エイリアス'games'は'reindex'とbackfillの後に切り替わります。落ち込んだフィールド-徐々に削除します。


9)スナップショット、DR、アップデート

オブジェクトストレージ(S3/GCS)へのスナップショット、スケジュールとリストアのチェック。
ノードのローリングアップデート、シャード割り当ての意識のチェック(ゾーン別)。
DR計画:重要なインデックス(ディレクトリ、ディレクトリ)のクロスリージョンレプリケーション(CCR)。


10)安全およびPII

クライアントとクラスタ間のTLS/mTLS。
RBAC:インデックス/操作あたりの役割。Dev/Stage/Prod-別途。
PII/PCI:不必要に個人データでフィールドをインデックスしないでください。インジェストマスキングを使用します。
忘れられる権利:user_idによる削除のためのドキュメントへのリンクを保持します。soft-delete+reindex/announcement。


11)観測可能性と検索SLO

メトリクス:
  • クエリーへの遅延P50/P95/P99、 4xx/5xxエラー。
  • キャッシュのヒット(クエリキャッシュ/シャードリクエストキャッシュ)。
  • ヒープの使用法、GCのマージ、セグメントマージ、スレッドプール(検索/書き込み)。
  • ホットシャード/ホットノード、拒絶。
  • KNN: 'graph_hits'、' search_k'、latency、 recall@k。
SLOの例:
  • ゲームの検索:P95 ≤ 200ミリ秒、エラー<0。30分のウィンドウで5%。
  • ヒント:P95 ≤ 80ミリ秒。
  • KNNハイブリッド:トップ20の結果のためのP95 ≤ 350ms。

12) FinOps: コストとパフォーマンス

インデックスサイズ:トークン化を保存し、不要な'fielddata'を無効にし、必要に応じて'doc_values'を使用します。
セグメント:マージポリシーを計画し、「分割」を許可しません。
KNNはRAM/CPUではより高価です:limit dims、 'num_candidents'、 BM25でのプリフィルタ。
RAMのホットフィールド:モニターフィールドデータ/ヒープ;「重い」集計を別のインデックスに取り込みます。


13)サンプル要求

13.1ブースト付きマルチフィールドフルテキスト

json
{
"query": {
"multi_match": {
"query": "book of",
"fields": ["title^4","title.ngram^2","tags^2","description"]
}
},
"sort": ["_score", { "released_at": "desc" }]
}

13.2フィルター+ファセット

json
{
"query": {
"bool": {
"must": [{ "match": { "title": "египет" }}],
"filter": [
{ "terms": { "provider": ["Novomatic","PragmaticPlay"]}},
{ "range": { "rtp": { "gte": 95 }}}
]
}
},
"aggs": {
"by_provider": { "terms": { "field": "provider" } },
"by_year": { "date_histogram": { "field": "released_at", "calendar_interval": "year" } }
}
}

13.3ネストされた属性フィルタリング

json
{
"query": {
"nested": {
"path": "features",
"query": { "bool": {
"must": [
{ "term": { "features.name": "volatility" }},
{ "term": { "features.value": "high" }}
]
}}
}
}
}

13.4ハイライト付きログ検索(ECS)

json
{
"query": {
"bool": {
"must": [{ "match_phrase": { "message": "payment declined" }}],
"filter": [
{ "term": { "service.name": "payments" }},
{ "range": { "@timestamp": { "gte": "now-1h" }}}
]
}
},
"highlight": { "fields": { "message": { "number_of_fragments": 0 } } }
}

14)複数のテナントおよび分離

テナントへのインデックス(より良い)またはフィールド'tenant_id'+ACLフィルタ(集計ではより高価)。
'tenant_id'でシャードをローカライズする。
テナントのリクエストを制限/タイムアウト、'クエリに制限します。フェーズのガードレール。


15)実装チェックリスト

1.スキーマ:'text/keyword/nested'+multi-fields、 'dense_vector'必要に応じて。
2.自動補完のための言語ごとのアナライザ、同義語、edge-ngram。
3.関連:BM25は+hybrid kNN→rescoreをブーストします。
4.ファセット:キーワード/ネスト、「健全な」フィールドのみの集計。
5.インデックス作成:ingest pipelines (normalization)、 batch loading。
6.Sharding:小さい、移動のエイリアス、「長い」ログのILMを開始します。
7.DR:スナップショットスケジュール、リカバリチェック、重要指標のCCR。
8.セキュリティ:TLS、 RBAC、 PIIマスキング、削除ポリシー。
9.観測可能性:レイテンシ、ヒープ/GC、キャッシュのヒット、ホットシャード、拒否。
10.FinOps:インデックスサイズ、kNNパラメータ化、余分な'doc_values/fielddata'を無効にします。


16)アンチパターン

「すべてのための」1つのインデックス:異なるドメイン(ディレクトリ、ログ、トランザクション)は、異なる設定を必要とします。
思慮のない「ファジネス:AUTO」→すべてのフィールドでゆっくりと騒々しい。
同義語「意味を食べる」:辞書のドメインを分離しないでください。
フィールドバンドル→偽ファセットが必要な場所にネストされていない。
あまりにも多くのシャード(ドキュメントごとに1つ)-クラスタ状態のオーバーヘッド。
移行中にエイリアスを使用しない-ダウンタイムとリンク切れ。
PIIインデックス化「そのまま」-規制リスクと高価な再インデックス。


17) iGamingコンテキスト/フィンテック: クイックレシピ

ゲームの検索:'multi_match'ブースト'title^4'、 'tags^2'、プロバイダ/ボラティリティによるファセット、地域/通貨によるフィルタ、"topics'のベクトル付きのハイブリッド(例えば"、エジプト"、"フルーツクラシック")。
プロモ/ボーナス:同義語(「フリースピン」、「フリースピン」)、データフィルタ'active_from/active_to'、完了までのヒント。
KYC/AMLログ:ECSスキーマ、'message'による全文、'rule_name'、 'country'による集計、'@timestamp'ヒストグラムによる異常。
プロバイダディレクトリ:ファセットとソートのキーワードフィールド;テキストの説明-形態学を持つ'text'。
規制ページ:多言語フィールド、ソフトヒントの'search_as_you_type'。


[結果]

Elasticsearchの効果的な検索は「BM25をオンにする」だけではありません。これらは適切なアナライザとマッピング、マルチフィールドとネスト、BM25+ベクトルのハイブリッド、きちんとしたファセットと集計、シャーディングとILMの規律、明確なSLOと観測性、安全性とFin Ops。これらの原則により、検索は迅速で関連性が高く予測可能になり、製品プラットフォームのトラフィックのピークに耐えます。

Contact

お問い合わせ

ご質問やサポートが必要な場合はお気軽にご連絡ください。いつでもお手伝いします!

統合を開始

Email は 必須。Telegram または WhatsApp は 任意

お名前 任意
Email 任意
件名 任意
メッセージ 任意
Telegram 任意
@
Telegram を入力いただいた場合、Email に加えてそちらにもご連絡します。
WhatsApp 任意
形式:+国番号と電話番号(例:+81XXXXXXXXX)。

ボタンを押すことで、データ処理に同意したものとみなされます。