🔎 搜索体验优化:ABP vNext 的查询改写(Query Rewrite)与同义词治理
📚 目录
- 🔎 搜索体验优化:ABP vNext 的查询改写(Query Rewrite)与同义词治理
-
- 1. 背景与问题界定 🧩
- 2. 总体架构(ABP 模块化 + 多租户 + 分层) 🏗️
- 3. 数据模型(PostgreSQL,含索引) 🧬
- 4. 改写管线(确定性顺序 + 可扩展) 🛠️
- 5. 拼写纠错(SymSpell + BK-Tree) ✍️
- 6. 同义词/别名治理(方向性 + 热更新) 🧠
- 7. 查询计划 → Elasticsearch DSL(去 `_all`,更稳的 `bool`/`dis_max`) 🧪
- 8. 点击反馈重排(轻量、弱监督、可回退) 🎯
- 9. 多租户与缓存治理(ABP 最佳实践) 🧰
- 10. 评测与观测 📊
- 11. 一键 Compose 🧪
- 12. 关键代码片段 🧩
- 13. 同义词热更新流程(SOP) 🛡️
- 15. 常见坑与规避 ⚠️
1. 背景与问题界定 🧩
痛点:零结果、弱相关、错拼(键邻/近音/形近)、品牌/部门别名不一致(“华为/HUAWEI/华爲”)、多叫法(“摄像头/相机/camera”)。
目标(示例):ZRR 下降 ≥ 30%(📉)、首条点击率 +10%(📈)、二次搜索率 -15%(📉)(以 AB 实验为准)。
约束:多租户隔离、可灰度、可回滚、可观测、可复现。
2. 总体架构(ABP 模块化 + 多租户 + 分层) 🏗️
-
模块:
Search.QueryRewriteModule(Domain/Application/HttpApi/Infrastructure)。 -
多租户:
ICurrentTenant贯穿数据、缓存、指标;缓存键必须包含TenantId;后台跨租户操作用ICurrentTenant.Change(...)。 -
存储分层:
- 检索面:Elasticsearch(中文分词 + 同义词 + DSL)
- 规则面:PostgreSQL(词典/规则/行为聚合)
- 热数据:Redis(24h CTR / Dwell Top-K;ABP 官方 Redis 模块支持批量
SetManyAsync/GetManyAsync)
-
流程:改写(检索前)→ ES 查询 → 轻量行为重排(可选 RRF 融合多路召回)。
🗺️ 架构总览(Mermaid)
3. 数据模型(PostgreSQL,含索引) 🧬
关键修正:
spell_lexicon主键改为(tenant_id, term),避免多租户冲突;为热路径增加索引。
create table synonym_set (
tenant_id uuid not null,
group_id uuid not null,
terms text[] not null,
direction smallint not null, -- 0: 双向, 1: 单向 from→to
boost double precision not null default 1.0,
version int not null default 1,
primary key (tenant_id, group_id)
);
create table alias (
tenant_id uuid not null,
entity_type text not null, -- brand/department/sku
key text not null,
aliases text[] not null,
boost double precision not null default 0.8,
primary key (tenant_id, entity_type, key)
);
create table spell_lexicon (
tenant_id uuid not null,
term text not null,
freq bigint not null default 0,
flags int not null default 0,
primary key (tenant_id, term)
);
create table rewrite_rule (
tenant_id uuid not null,
id uuid not null,
cond_json jsonb not null, -- {"category":"phone"}
action_json jsonb not null, -- {"extend":["phone case","保护壳"]}
weight double precision not null default 1.0,
active_from timestamptz,
active_to timestamptz,
primary key (tenant_id, id)
);
create table click_log (
tenant_id uuid not null,
query text not null,
doc_id text not null,
clicked boolean not null,
dwell_ms int,
ts timestamptz not null default now()
);
-- 索引建议
create index idx_syn_terms on synonym_set using gin (terms);
create index idx_alias_key on alias(

最低0.47元/天 解锁文章
1246

被折叠的 条评论
为什么被折叠?



