GH GambleHub

过滤和全文搜索

1)为什么需要搜索层

过滤和全文搜索(FTS)可以快速访问"意义上"的数据,而不仅仅是主要密钥。正确设计的搜索层结合了以下内容:
  • 严格的过滤器(类别、日期、价格、访问权限)
  • 全文(词汇匹配和排名)
  • 立面(用于导航的聚合)
  • 溷合排名(BM25/TF-IDF+矢量栓塞)
  • 强大的协议(光标分页、TTL令牌、交叉分码)

2)建筑绘画

组件:

1.Ingest/ETL →规范化、重复数据消除、丰富、索引字段构建。

2.索引器→反索引(词素→文档),柱结构,矢量索引(HNSW/IVF-PQ)。

3.Query Layer →请求解析器、过滤器/访问权限应用、shard调度程序、k-way merge。

4.Ranker → BM25+(opz。)LTR/Neural re-rank.

5.Serving →缓存、光标、立面、高线、自动配方。

6.可观察性→潜伏度指标,质量,A/B实验。

3)数据和索引模型

3.1字段和分析仪

类型:keyword(均匀匹配)、text(分析)、numeric/date/geo、vector。
分析仪:令牌化,正常化(lowercase, Unicode NFKC),过滤器(停止词,stemming/lemmatization)。
多语言:按字段分析(ru,uk,en);ICU分析;音译;考虑变音符号。

3.2反向索引(sparse)

结构:term → posting list(docID,term freq,位置)。
排名:具有现场助推器的BM25(或经典TF-IDF)。

3.3向量索引(dense)

文本的Embeddings(例如384-1024维)。
ANN结构:HNSW,IVF-PQ,平面(用于小集)。
余弦接近/内置产品;BM25校准(溷合体)。

3.4面和单元

快速计数值的前奏/柱形存储。
分层立面(类别/子类别)。
范围(价格桶,日期)。

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安全,连字符/撇号计数。
停止单词:按语言排列的调音列表。
Stemming vs lemmatization:对于ru/uk来说,lemmatization更好(质量>速度)。
同义词:双向/定向字典;TTL字典版本。
错字(fuzzy):Damerau-Levenshtein具有距离限制和精确匹配的助推器。
N-grams/edge-ngrams:用于自动配方和提示。
音译:"shch" ↔ "sht","kiev/kyiv"是对应规则。

6)相关性和排名

6.1基本词汇评分

BM25按集合设置"k1","b"。

横跨字段的助推器(标题^3,标题^1.5, body^1).

新鲜:"score+=freshness_boost(decay(created_at))"。

6.2行为信号

点击率,dwell时间,保存到收藏夹中(带有反位置巴亚斯)。
重复数据消除:将具有~相同内容的文档(MinHash/SimHash)粘贴在一起。

6.3 Learning-to-Rank (LTR)

菲奇:田野BM25,长度,新鲜,人气,短语匹配和位置争吵。
型号:LambdaMART/XGBoost;离线指标NDCG@k,MAP,Precision@k;A/B在线。

6.4神经重新安排

两步:recall (BM25/ANN) → top-N(例如200) → cross-encoder rerank。
成本核算:超时预算,在负载下没有神经阶段后退。

6.5溷合搜索(sparse+dense)

Fusion(标量归一化和总和)或多阶段(dense为rerank)。
校准很重要:min-max/z-score/quantile映射。

7)过滤,面和访问

7.1个过滤器

运算符:'=','IN',范围,前缀,geo-bounding box/geo-distance。
组合:"AND"通过过滤器,"OR"在多个值内(品牌IN……)。
类型安全:数值字段不分析为文本。

7.2 Fasets

在预期的结构上廉价计数。
"应用"面板显示剩余的变体(后过滤器面部)。

7.3访问/多影子

安全过滤器集成到排名(预过滤器)之前。
文档中字段的ABAC/RBAC("tenant_id","visibility","acl")。
请求令牌已签名;多重特南特是自动"tenant_id"过滤器。

8)分离,游标和一致性

在按时间排序时,通过"(得分,决胜局)"或"(created_at,id)"通过seek游标进行分区。
不透明的"page_token" c HMAC和TTL。
一致性:索引的近实时(NRT):延迟0。5-2与记录和可见性之间。在SLA中记录这一点。
Cross Shard:通过全局顺序本地搜索→ k-way merge,令牌中的每包游标。

9)自动补充和提示

Suggesters: prefix-trie / edge-ngrams по полю `title`.

Popular queries:点击日志→人气线索+个性化(片段)。
Spell-as-you-type:具有距离限制'<=1'的快速fuzzy搜索。

REST示例:

GET /v1/suggest? q=kaz&limit=8&locale=ru
→ ["casino," "casual games,..."]

10)Highlight和snippets

位置索引→提取匹配的短语。
HTML屏蔽,长度限制,相邻片段合并。
根据相关术语的密度对嗅觉进行排名。

11)性能、缓存和SLO

索引:内存中的热段;邮寄压缩;立面的doc values。
缓存:L1(过程),L2(Redis),立面/聚合缓存;根据索引版本残疾。

SLO: P95 <150-200毫秒,"k<=20",P99 <500毫秒;99的可用性。9%.

Backpressure:减少"k",超载时关闭神经阶段。
在API/用户/tenant密钥上排名限制。

12)可观察性和质量指标

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在标记样本中。
在线:
  • CTR@k, sCTR (satisfied clicks), dwell time, отказ (pogostick rate).

A/B:捕获"guardrail"度量(潜伏、错误)+目标(NDCG proxy)。

13)测试

Relevance unit tests:检查关键请求的预期匹配。
基于属性的:对打印错误/同义词/语言的抗性。
分页:页面边界上没有重复内容(seek合同)。
安全性:访问过滤器始终适用(即使在faset-count)。
字典倒退:同义词和fuzzy规则的转换。

14)安全和隐私

带有PII的字段不作为文本索引;单独存储/加密。
最大程度地减少存储的源文本(store=false,仅用于嗅探的字段)。
查询隐私:不要用PII来计算原始查询;匿名/散列。
多功能:严格的索引隔离或强制性的"tenant_id"过滤器。

15)迁移和互操作性

双重记录和逐步切换的索引方案(v1→v2)的转换。
分析仪兼容性:保持旧链不被重新索引。
同义词/停止单词词典的轮换:"version","activated_at",rollback。

16)实用食谱

16.1经典词汇搜索(BM25)

字段:"title^3","tags^2","body^1"。
分析仪:语言特定+语言化。
短查询的Fuzzy("<=3"令牌),"fuzziness=1"。

16.2 sparse+dense溷合体

1.ANN搜索(k=200)

2.与top-200合并BM25

3.校准和排干(Reciprocal Rank Fusion)

4.选择top-N (N=20),可选地-以足够的预算进行交叉编码。

16.3面目录导航

强硬的权利预过滤器/tenant

后过滤器筋膜(计入活动过滤器)

排序: 按相关性或业务领域(价格/新颖性)

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模式

有源过滤器芯片+"全部重置"。
空白结果:显示"尝试……"(同义词,删除过滤器)。
"零提示":流行的查询/类别。
游标分区("更多"按钮)和无限滚动;应用过滤器的固定指示灯。
单独的开关"考虑错字","短语的精确匹配"。

19)频繁的错误和反模式

排序时缺少决胜局→双打/赛马。
不考虑活动过滤器的面板→"假"计数。
排名后应用访问过滤器。
通过单个分析仪混合不同的语言。
深层分区OFFSET/LIMIT代替seek游标。
无限的fuzzy →潜伏期爆炸。

20)实施清单

1.定义字段及其类型,指定per-locale分析器。
2.设计反向索引+(opz.)向量ANN。
3.实现查询解析器和安全访问过滤器(预过滤器)。
4.调整BM25和现场助推器;连接筋膜。
5.输入光标(opaque、HMAC、TTL)和k-way merge。
6.添加自动放大器、高亮度、安全屏蔽。
7.度量:潜伏期,NDCG@k,CTR;快取L1/L2。
8.A/B框架用于调谐相关性。
9.记录SLA: NRT延迟、"极限"限制、一致性保证。
10.迁移计划:索引,词典和分析器的版本。

设计精良的过滤和全文搜索层不仅是一个快速的索引,而且还与光标,安全性,可预测的UX和可测量的相关性签订了明确的协议合同。这种方法可以扩展到数千到数十亿份文档,并支持经典词汇搜索和具有神经网络排名的现代混合场景。

Contact

联系我们

如需任何咨询或支持,请随时联系我们。我们随时准备提供帮助!

Telegram
@Gamble_GC
开始集成

Email — 必填。Telegram 或 WhatsApp — 可选

您的姓名 可选
Email 可选
主题 可选
消息内容 可选
Telegram 可选
@
如果填写 Telegram,我们也会在 Telegram 回复您。
WhatsApp 可选
格式:+国家代码 + 号码(例如:+86XXXXXXXXX)。

点击按钮即表示您同意数据处理。