Filterung und Volltextsuche
1) Warum brauchen Sie eine Suchebene
Filterung und Volltextsuche (FTS) ermöglichen einen schnellen Zugriff auf Daten „nach Bedeutung“ und nicht nur nach Primärschlüsseln. Eine richtig gestaltete Suchebene kombiniert:- Strenge Filter (Kategorien, Termine, Preise, Zugriffsrechte)
- Volltext (lexikalisches Match und Ranking)
- Facetten (Aggregate zur Navigation)
- Hybrides Ranking (BM25/TF-IDF + Vektor-Embeddings)
- Robuste Protokolle (Cursor-Paginierung, TTL-Token, Cross-Sharding)
2) Architektonisches Bild
Die Komponenten sind:1. Ingest/ETL → Normalisierung, Deduplizierung, Anreicherung, Feldbildung für den Index.
2. Indexer → umgekehrter Index (Lexeme → Dokumente), Säulenstrukturen, Vektorindex (HNSW/IVF-PQ).
3. Query Layer → Abfrage-Parser, Anwendung von Filtern/Zugriffsrechten, Shard Scheduler, k-way merge.
4. Ranker → BM25 + LTR/Neural re-rank.
5. Serving → Cache, Cursor, Facetten, Highlights, Auto-Set.
6. Beobachtbarkeit → Metriken Latenz, Qualität, A/B-Experimente.
3) Daten- und Indexmodell
3. 1 Felder und Analysatoren
Typen: keyword (ebenmäßige Übereinstimmung), text (analysiert), numeric/date/geo, vector.
Analysatoren: Tokenisierung, Normalisierung (Lowercase, Unicode NFKC), Filter (Stoppwörter, Stemming/Lemmatisierung).
Mehrsprachigkeit: Per-Field-Analysatoren (ru, uk, en); ICU-Analyse; Transliteration; Berücksichtigung der Diakritik.
3. 2 Umgekehrter Index (Sparse)
Struktur: term → posting list (docID, term freq, Positionen).
Ranking: BM25 (oder klassisches TF-IDF) mit Feldboosts.
3. 3 Vektorindex (Dense)
Embeddings des Textes (z.B. 384-1024-dimensional).
ANN-Strukturen: HNSW, IVF-PQ, Flat (für kleine Sets).
Kosinusnähe/inneres Produkt; Kalibrierung mit BM25 (Hybrid).
3. 4 Facetten und Aggregate
Präcomputer-/Säulenspeicherung von Werten für schnelle Zählungen.
Hierarchische Facetten (Kategorie/Unterkategorie).
Bereiche (Preisklassen, Termine).
4) Anfragen: Filter + Volltext + Sortierung
4. 1 API-Verträge (REST)
Anfrage:
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)
Antwort (Fragment):
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 (vereinfacht)
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) Verarbeitung natürlicher Sprache (NLP)
Tokenisierung/Normalisierung: Unicode-sicher, Berücksichtigung von Bindestrichen/Apostrophen.
Stoppwörter: Einstellungslisten nach Sprachen.
Stemming vs Lemmatisierung: Für ru/uk ist die Lemmatisierung besser (Qualität> Geschwindigkeit).
Synonyme: bidirektionale/direktionale Wörterbücher; Wörterbuchversionen mit TTL.
Tippfehler (fuzzy): Damerau-Levenshtein mit Abstandsbeschränkung und Boostern der genauen Übereinstimmung.
N-grams/edge-ngrams: für Auto-Set und Hinweise.
Transliteration: „shch“ ↔ „sch“, „kiev/kyiv“ - Regeln der Entsprechungen.
6) Relevanz und Ranking
6. 1 Grundlegendes lexikalisches Scoring
BM25 mit der Einstellung 'k1','b 'durch die Sammlung.
Feldboosts (Titel ^ 3, Tags ^ 1. 5, body^1).
Frische: „score + = freshness_boost (decay (created_at))“.
6. 2 Verhaltenssignale
Click-through rate, dwell time, speichern in Favoriten (mit Anti-Position-Byas).
Deduplizierung: Kleben von Dokumenten mit ~ identischem Inhalt (MinHash/SimHash).
6. 3 Learning-to-Rank (LTR)
Fichi: BM25 nach Feldern, Länge, Frische, Popularität, Übereinstimmung nach Phrase, Positionsneigung.
Modelle: LambdaMART/XGBoost; Offline-Metriken NDCG @ k, MAP, Precision @ k; Online A/B.
6. 4 Neuro-Neuordnung
Zwei Stufen: recall (BM25/ANN) → top-N (z.B. 200) → cross-encoder rerank.
Kostenrechnung: Zeitbudget, Fallback ohne Neuro-Phase unter Last.
6. 5 Hybride Suche (sparse + dense)
Entweder Fusion (Normalisierung der Skoren und Summe) oder Multi-Stage (Dense als Rerank).
Wichtig ist die Kalibrierung: min-max/z-score/quantile mapping.
7) Filterung, Facetten und Zugang
7. 1 Filter
Operatoren:'=', 'IN', Bereiche, Präfixe, geo-bounding box/geo-distance.
Kombinationen: 'AND' durch Filter, 'OR' innerhalb einer Vielzahl von Werten (Marke IN...).
Typsicherheit: Numerische Felder werden nicht als Text analysiert.
7. 2 Facetten
Billige Count-s durch vorhergesagte Strukturen.
„Applied“ Facetten zeigen die verbleibenden Varianten (Post-Filter Faceting).
7. 3 Zugang/Multi-Tenant
Sicherheitsfilter werden vor dem Ranking integriert (Pre-Filter).
ABAC/RBAC-Felder im Dokument ('tenant _ id', 'visibility', 'acl').
Das Anforderungstoken ist signiert; bei Multi-Tenant - automatischer 'tenant _ id' Filter.
8) Paginierung, Cursor und Konsistenz
Seek-Cursor-Paginierung durch'(score, tie-breaker) 'oder durch' (created_at, id)', wenn nach Zeit sortiert.
Undurchsichtige' page _ token'c HMAC und TTL.
Konsistenz: near-real-time (NRT) Index: Verzögerung 0. 5-2 s zwischen Aufnahme und Sichtbarkeit. Dokumentieren Sie dies im SLA.
Cross-Shard: Lokale Suche → k-way merge durch globale Ordnung, per-shard Cursor im Token.
9) Auto-Vervollständigung und Hinweise
Suggesters: prefix-trie / edge-ngrams по полю `title`.
Popular Queries: Klickprotokoll → Tipps zur Popularität + Personalisierung (Segmente).
Spell-as-you-type: schnelle Fuzzy-Suche mit Abstandsbeschränkung'<= 1'.
GET /v1/suggest? q=kaz&limit=8&locale=ru
→ ["casino," "casual games,..."]
10) Highlights und Snippets
Der Positionsindex → die Extraktion von Phrasen mit Übereinstimmungen.
HTML-Abschirmung, Längenbegrenzung, Zusammenführen benachbarter Fragmente.
Rangfolge der Snippets nach der Dichte der relevanten Begriffe.
11) Leistung, Cache und SLO
Indizes: heiße Segmente im Speicher; Kompression von Postings; doc Werte für Facetten.
Cache: L1 (Prozess), L2 (Redis), Facetten/Aggregate Cache; Behinderung nach der Version des Index.
SLO: P95 <150-200 ms bei „k <= 20“, P99 <500 ms; Verfügbarkeit 99. 9%.
Backpressure: Reduktion'k', Abschalten der Neuro-Phase bei Überlastung.
Rate limiting pro API/User/Tenant Schlüssel.
12) Beobachtbarkeit und Qualitätsmetriken
Techmetrics:- `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 auf den markierten Proben.
- CTR@k, sCTR (satisfied clicks), dwell time, отказ (pogostick rate).
A/B: Erfassen Sie „guardrail“ Metriken (Latenz, Fehler) + Ziel (NDCG Proxy).
13) Testen
Relevante Einheitstests: Überprüfen Sie die erwarteten Matches auf Schlüsselanforderungen.
Property-based: Resistenz gegen Tippfehler/Synonyme/Sprachen.
Paginierung: keine Duplikate am Seitenrand (Seek-Verträge).
Sicherheit: Zugriffsfilter gelten immer (auch bei Faset-Count).
Wörterbuchregressionen: Versionierung von Synonymen und Fuzzy-Regeln.
14) Sicherheit und Privatsphäre
Felder mit PII nicht als Text indizieren; separat speichern/verschlüsseln.
Minimierung der gespeicherten Quelltexte (store = false, nur Felder für Snippets).
Abfrage-Datenschutz: keine rohen Abfragen mit PII protokollieren; Anonymisierung/Hash.
Multi-Tenant: strikte Indexisolierung oder obligatorischer 'tenant _ id' Filter.
15) Migrationen und Kompatibilität
Versionierung des Indexschemas (v1→v2) mit doppeltem Schreiben und allmählichem Umschalten.
Kompatibilität der Analysatoren: Halten Sie die alten Ketten, bis Sie neu indizieren.
Rotation von Synonym-Wörterbüchern/Stoppwörtern: 'version', 'activated _ at', rollback.
16) Praktische Rezepte
16. 1 Klassische lexikalische Suche (BM25)
Felder: 'title ^ 3', 'tags ^ 2', 'body ^ 1'.
Analysatoren: sprachspezifisch + Lemmatisierung.
Fuzzy für kurze Anfragen ('<= 3 'Token),' fuzziness = 1'.
16. 2 Sparse + Dense Hybrid
1. ANN-Suche nach Anfrage-Embedding (k = 200)
2. Mit Top-200 kombinieren BM25
3. Kalibrieren und Ablassen (Reciprocal Rank Fusion)
4. Nehmen Sie Top-N (N = 20), optional - Rerank Cross-Encoder mit ausreichendem Budget.
16. 3 Facettierte Katalognavigation
Harter Vorfilter nach Rechten/Tenant
Post-Filter Facetten (counts unter Berücksichtigung der aktiven Filter)
Sortierung: nach Relevanz oder nach Geschäftsfeld (Preis/Neuheit)
17) Beispielabfragen (Pseudo-DSL)
Filter und Sortierung: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"}
}
Geo-Suche:
json
{
"query": "casino",
"geo": {"lat": 59. 437, "lon": 24. 753, "radius_km": 50}
}
Auto-Set:
json
{ "prefix": "evo", "field": "brand_suggest", "limit": 8 }
18) UX-Muster
Aktive Filterchips + „Alles zurücksetzen“.
Leere Ergebnisse: zeigen „versuchen...“ (Synonyme, Filter entfernen).
„Hinweise bei Null“: Beliebte Suchanfragen/Kategorien.
Cursor-Paginierung (Mehr-Taste) und endloses Scrollen; fester Indikator der angewendeten Filter.
Die einzelnen Schalter „berücksichtigen Tippfehler“, „genaue Übereinstimmung der Phrase“.
19) Häufige Fehler und Anti-Muster
Kein Tie-Breaker beim Sortieren → Doppel/Pferderennen.
Facetten ohne aktive Filter → „falsche“ Counts.
Anwenden von Zugriffsfiltern nach dem Ranking.
Mischen verschiedener Sprachen mit einem Analysator.
Tiefe OFFSET/LIMIT Paginierung statt Seek-Cursor.
Unbegrenzte fuzzy → Explosion durch Latenz.
20) Implementierungs-Checkliste
1. Definieren Sie die Felder und ihre Typen, weisen Sie per-locale Analysatoren zu.
2. Entwerfen Sie einen umgekehrten Index + (opz.) Vektor ANN.
3. Implementieren Sie einen Anforderungsparser und sichere Zugriffsfilter (Pre-Filter).
4. Richten Sie BM25 und Feldboosts ein; Verbinden Sie die Facetten.
5. Geben Sie Cursor (opaque, HMAC, TTL) und k-way merge über shards ein.
6. Fügen Sie Auto-Kit, Highlights, sichere Abschirmung hinzu.
7. Metriken: Latenz, NDCG @ k, CTR; Cache von L1/L2.
8. A/B-Framework zur Abstimmung der Relevanz.
9. SLA dokumentieren: NRT-Latenz, Limits' Limit', Konsistenzgarantie.
10. Migrationsplan: Versionen von Index, Wörterbüchern und Analysatoren.
Eine gut gestaltete Filter- und Volltextsuchschicht ist nicht nur ein schneller Index, sondern auch ein klarer Protokollvertrag mit Cursors, Sicherheit, vorhersehbarer UX und messbarer Relevanz. Dieser Ansatz skaliert von Tausenden bis Milliarden von Dokumenten und unterstützt sowohl die klassische lexikalische Suche als auch moderne hybride Szenarien mit neuronalem Netzwerk-Ranking.