SOLR

Solr父子文档在文档检索中的实战应用

Solr父子文档在文档检索中的实战应用从需求到实现,解决文档级全文检索的五个关键问题大家好,我是负责公司知识库搜索模块的后端开发。最近我们重构了文档检索功能,目标是让用户搜索“文档”本身,而不是零散的内容片段。今天就把这套基于Solr父子文档+EDisMax的方案拆开揉碎,分享给正在做类似需求的朋友。一、业务场景:搜的是“文档”,不是“段落”我们的文档库包含大量技术规程、作业指导书,每篇文档有标题

Solr父子文档在文档检索中的实战应用

从需求到实现,解决文档级全文检索的五个关键问题

大家好,我是负责公司知识库搜索模块的后端开发。最近我们重构了文档检索功能,目标是让用户搜索“文档”本身,而不是零散的内容片段。今天就把这套基于 Solr 父子文档 + EDisMax 的方案拆开揉碎,分享给正在做类似需求的朋友。


一、业务场景:搜的是“文档”,不是“段落”

我们的文档库包含大量技术规程、作业指导书,每篇文档有标题、标签、目录结构,正文被切分为多个内容块(如章节、表格)。用户输入一段话,期望的是:

  • 按文档维度返回列表:同一文档里命中 10 处,只算 1 个文档,不能重复刷屏;

  • 全字段检索:标题、标签、目录标题、正文、表头、页脚,哪儿命中都行;

  • 分页按文档数算:total 是文档总数,翻页在文档列表上翻;

  • 中文长短语友好:“10kV 带电作业安全距离”这种长词,不能因为分词太碎而召回 0 条。

传统方案里,如果直接对内容块建索引,搜出来全是段落 ID,前端还得按文档聚合、手动分页,既麻烦又容易出错。所以我们重新设计了索引结构——Solr 父子文档。


二、整体架构:一条清晰的数据流水线

关系库 → 同步工具 → Solr(父子文档) → 查询接口 → 前端展示
  • 数据源:MySQL,三张核心表:文档表、目录表、内容块表。

  • 索引层:Solr 8.11,父文档存文档级信息,子文档存每个内容块。

  • 同步层:Java 定时任务,将三张表 JOIN 后灌入 Solr。

  • 查询层:接口接收关键词、分页参数,构造 {!parent which=...} 查询,强制返回父文档。

  • 展示层:列表显示文档卡片,点击进入详情再高亮具体内容块。

这套流水线的核心,就是 “子文档命中,父文档现身”。


三、数据建模:父子文档怎么设计?

1. 数据库表(简化版)

  • doc_documents:文档 ID、标题、标签、浏览/下载数……

  • doc_outline_nodes:目录节点 ID、所属文档、父节点、标题、层级、页码。

  • doc_content_blocks:内容块 ID、所属文档、关联目录、正文、表头/页脚、页码、排序。

一个文档 → 多个目录节点 → 多个内容块,典型的一对多。

2. Solr 父子文档字段设计

父文档(文档维度)

  • 常规字段:title(中文分词)、image(不分词)、各类计数(plongs/pint)

  • 标签字段:tag_comprehensive、tag_technical、tag_business(中文分词)

  • 目录聚合字段:多值字段,如 outline_title、outline_level,把目录标题全部塞进来,方便直接命中目录关键词

  • 全局检索字段:search_all,通过 copyField 汇集 title + outline_title + content_text(可选),简化跨字段查询

子文档(内容块维度)

  • parent_id:指向父文档 ID(关键关联)

  • content_text:正文(中文分词,权重最高)

  • header_list / footer_list:表格标题(中文分词,权重次之)

  • page_number、sort_order:用于排序和高亮定位

为什么把目录信息也冗余到父文档?
因为用户搜目录标题时,我们希望直接由父文档命中,不需要走子文档再折返。这是提升性能的小技巧。


四、索引同步:如何把关系数据变成父子文档?

同步步骤并不复杂,核心是 聚合 + 分批次。

// 伪代码示意
List<D

原创不易,完成人机校验,阅读全文

相关推荐