smart_rag 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env.example +252 -0
- data/.rspec +2 -0
- data/AGENTS.md +33 -0
- data/API_DOCUMENTATION.md +828 -0
- data/CHANGELOG.md +11 -1
- data/ER-diagram.mmd +144 -0
- data/Gemfile +50 -0
- data/Gemfile.lock +381 -0
- data/Hybrid_Reranking.md +171 -0
- data/README.en.md +420 -28
- data/README.md +534 -63
- data/Rakefile +268 -0
- data/SETUP_GUIDE.md +650 -0
- data/SmartChunking.md +180 -0
- data/USAGE_EXAMPLES.md +1002 -0
- data/config/llm_config.yml +4 -2
- data/config/smart_rag.yml +45 -1
- data/config.ru +15 -0
- data/db/migrations/006_create_text_search_configs.rb +3 -2
- data/db/migrations/008_create_embeddings.rb +5 -4
- data/db/migrations/012_add_metadata_to_source_sections.rb +11 -0
- data/db/migrations/013_create_media_jobs.rb +25 -0
- data/db/migrations/014_add_media_job_operations_indexes.rb +11 -0
- data/db/migrations/015_add_media_leases_and_objects.rb +80 -0
- data/db/migrations/016_add_document_principals_and_staging_references.rb +38 -0
- data/db/migrations/017_add_media_job_request_fingerprint.rb +48 -0
- data/db/seeds/text_search_configs.sql +3 -3
- data/design.md +1057 -0
- data/docs/API_DOCUMENTATION.md +838 -0
- data/docs/DOCUMENTATION_INDEX.en.md +60 -0
- data/docs/DOCUMENTATION_INDEX.md +65 -0
- data/docs/FIX_SUMMARY.md +256 -0
- data/docs/FIX_SUMMARY_COMPLETE.md +273 -0
- data/docs/Hybrid_Reranking.md +171 -0
- data/docs/MIGRATION_GUIDE.md +151 -0
- data/docs/PERFORMANCE_GUIDE.md +58 -0
- data/docs/SETUP_GUIDE.md +659 -0
- data/docs/SmartChunking.md +180 -0
- data/docs/USAGE_EXAMPLES.md +1008 -0
- data/docs/design.md +1057 -0
- data/docs/evidence_pack.md +211 -0
- data/docs/requirements.md +376 -0
- data/docs/retrieval_plan.md +251 -0
- data/docs/smartrag_improvement_plan.md +201 -0
- data/docs/smartrag_refactor.md +216 -0
- data/docs/todo.md +931 -0
- data/examples/common.rb +1 -1
- data/exe/smart-rag-db +163 -0
- data/exe/smart-rag-media-worker +34 -0
- data/lib/smart_rag/config.rb +12 -0
- data/lib/smart_rag/core/document_processor.rb +80 -16
- data/lib/smart_rag/core/local_content_store.rb +51 -0
- data/lib/smart_rag/core/media_extractors.rb +140 -0
- data/lib/smart_rag/core/media_job_queue.rb +353 -0
- data/lib/smart_rag/core/media_metadata_extractor.rb +188 -0
- data/lib/smart_rag/core/media_object_registry.rb +79 -0
- data/lib/smart_rag/core/media_processor.rb +228 -0
- data/lib/smart_rag/core/media_safety_policy.rb +61 -0
- data/lib/smart_rag/core/s3_content_store.rb +78 -0
- data/lib/smart_rag/core/transcript_normalizer.rb +44 -0
- data/lib/smart_rag/core/video_semantic_extractor.rb +130 -0
- data/lib/smart_rag/http_access_policy.rb +86 -0
- data/lib/smart_rag/http_app.rb +188 -0
- data/lib/smart_rag/models/embedding.rb +1 -1
- data/lib/smart_rag/models/research_topic.rb +1 -1
- data/lib/smart_rag/models/research_topic_section.rb +5 -0
- data/lib/smart_rag/models/research_topic_tag.rb +5 -0
- data/lib/smart_rag/models/search_log.rb +1 -1
- data/lib/smart_rag/models/section_fts.rb +5 -0
- data/lib/smart_rag/models/section_tag.rb +5 -0
- data/lib/smart_rag/models/source_document.rb +1 -1
- data/lib/smart_rag/models/source_section.rb +1 -1
- data/lib/smart_rag/models/tag.rb +1 -1
- data/lib/smart_rag/models/text_search_config.rb +5 -0
- data/lib/smart_rag/retrieve.rb +72 -1
- data/lib/smart_rag/services/embedding_service.rb +1 -1
- data/lib/smart_rag/services/fulltext_search_service.rb +11 -13
- data/lib/smart_rag/services/hybrid_search_service.rb +15 -11
- data/lib/smart_rag/services/summarization_service.rb +1 -1
- data/lib/smart_rag/services/tag_service.rb +1 -1
- data/lib/smart_rag/version.rb +1 -1
- data/lib/smart_rag.rb +264 -30
- data/patch_language.rb +27 -0
- data/requirements.md +376 -0
- data/source_documents_export.json +11072 -0
- data/todo.md +931 -0
- data/workers/analyze_content.rb +6 -2
- data/workers/get_embedding.rb +1 -1
- metadata +151 -38
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Documentation Index
|
|
2
|
+
|
|
3
|
+
[中文版](DOCUMENTATION_INDEX.md)
|
|
4
|
+
|
|
5
|
+
This document provides a consolidated map of the current documentation set, including purpose, audience, and suggested reading order.
|
|
6
|
+
|
|
7
|
+
## Recommended Reading Path
|
|
8
|
+
|
|
9
|
+
1. `../README.en.md`
|
|
10
|
+
Project entry and quick start
|
|
11
|
+
2. `SETUP_GUIDE.md`
|
|
12
|
+
Detailed environment and deployment setup
|
|
13
|
+
3. `API_DOCUMENTATION.md`
|
|
14
|
+
API reference
|
|
15
|
+
4. `USAGE_EXAMPLES.md` + `../examples/README.md`
|
|
16
|
+
Practical patterns and runnable examples
|
|
17
|
+
5. `PERFORMANCE_GUIDE.md` and `Hybrid_Reranking.md`
|
|
18
|
+
Performance tuning and ranking strategy
|
|
19
|
+
6. `MIGRATION_GUIDE.md`
|
|
20
|
+
Upgrade and compatibility notes
|
|
21
|
+
|
|
22
|
+
## Document Catalog
|
|
23
|
+
|
|
24
|
+
| File | Language | Purpose | Primary Audience |
|
|
25
|
+
|---|---|---|---|
|
|
26
|
+
| `../README.md` | Chinese | Project overview, quick start, command entry | All users |
|
|
27
|
+
| `../README.en.md` | English | Project overview and quick start | English readers |
|
|
28
|
+
| `SETUP_GUIDE.md` | Chinese | Environment setup and deployment | DevOps / backend engineers |
|
|
29
|
+
| `API_DOCUMENTATION.md` | Chinese | API descriptions and examples | Integrators / backend developers |
|
|
30
|
+
| `USAGE_EXAMPLES.md` | English | End-to-end usage patterns and best practices | Application developers |
|
|
31
|
+
| `../examples/README.md` | English | Runnable script map and usage | New adopters |
|
|
32
|
+
| `PERFORMANCE_GUIDE.md` | English | Search and DB performance guidance | Performance engineers |
|
|
33
|
+
| `Hybrid_Reranking.md` | English | Hybrid retrieval and reranking notes | Search relevance engineers |
|
|
34
|
+
| `SmartChunking.md` | English | Chunking strategy details | Ingestion pipeline developers |
|
|
35
|
+
| `MIGRATION_GUIDE.md` | English | Version migration process | Maintainers |
|
|
36
|
+
| `../test/README.md` | Chinese | Test dataset notes | QA / developers |
|
|
37
|
+
| `../test/TEST_GUIDE.md` | Chinese | Manual testing scripts and scenarios | QA / developers |
|
|
38
|
+
| `design.md` | English | System design notes | Architects / maintainers |
|
|
39
|
+
| `requirements.md` | English | Requirement definition | Product / architecture reviewers |
|
|
40
|
+
| `FIX_SUMMARY.md` | English | Intermediate fix summary | Maintainers |
|
|
41
|
+
| `FIX_SUMMARY_COMPLETE.md` | English | Consolidated fix report | Maintainers |
|
|
42
|
+
| `todo.md` | English | Backlog and pending tasks | Maintainers |
|
|
43
|
+
|
|
44
|
+
## Gaps and Alignment Notes
|
|
45
|
+
|
|
46
|
+
- Some docs still use older defaults (for example OpenAI snippets). Runtime source of truth is `../config/smart_rag.yml`.
|
|
47
|
+
- Language coverage is currently uneven: some docs are Chinese-only, some are English-only. Add translated counterparts by priority.
|
|
48
|
+
|
|
49
|
+
## Maintenance Policy
|
|
50
|
+
|
|
51
|
+
- When API signatures change, update at least:
|
|
52
|
+
- `../lib/smart_rag.rb`
|
|
53
|
+
- `API_DOCUMENTATION.md`
|
|
54
|
+
- `USAGE_EXAMPLES.md`
|
|
55
|
+
- `../examples/*.rb`
|
|
56
|
+
- When default configuration changes, update at least:
|
|
57
|
+
- `../.env.example`
|
|
58
|
+
- `../config/smart_rag.yml`
|
|
59
|
+
- `../README.md`
|
|
60
|
+
- `../README.en.md`
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# 文档总览
|
|
2
|
+
|
|
3
|
+
[English Version](DOCUMENTATION_INDEX.en.md)
|
|
4
|
+
|
|
5
|
+
本文档用于统一梳理当前文档,说明用途、目标读者与推荐阅读顺序。
|
|
6
|
+
|
|
7
|
+
## 推荐阅读路径
|
|
8
|
+
|
|
9
|
+
1. `../README.md`
|
|
10
|
+
项目入口与快速启动
|
|
11
|
+
2. `SETUP_GUIDE.md`
|
|
12
|
+
环境与部署详细安装指南
|
|
13
|
+
3. `API_DOCUMENTATION.md`
|
|
14
|
+
API 参考说明
|
|
15
|
+
4. `USAGE_EXAMPLES.md` + `../examples/README.md`
|
|
16
|
+
实战用法与可运行示例
|
|
17
|
+
5. `PERFORMANCE_GUIDE.md` 与 `Hybrid_Reranking.md`
|
|
18
|
+
性能调优与排序策略
|
|
19
|
+
6. `MIGRATION_GUIDE.md`
|
|
20
|
+
版本迁移与兼容说明
|
|
21
|
+
7. `smartrag_improvement_plan.md` + `retrieval_plan.md` + `evidence_pack.md`
|
|
22
|
+
SmartRAG 重构计划与检索契约
|
|
23
|
+
|
|
24
|
+
## 文档目录梳理
|
|
25
|
+
|
|
26
|
+
| 文件 | 语言 | 用途 | 主要读者 |
|
|
27
|
+
|---|---|---|---|
|
|
28
|
+
| `../README.md` | 中文 | 项目概览、快速开始、命令入口 | 所有用户 |
|
|
29
|
+
| `../README.en.md` | 英文 | Project overview and quick start | English readers |
|
|
30
|
+
| `SETUP_GUIDE.md` | 中文 | 环境安装与部署 | DevOps / 后端工程师 |
|
|
31
|
+
| `API_DOCUMENTATION.md` | 中文 | API 说明与示例 | 接入开发者 |
|
|
32
|
+
| `USAGE_EXAMPLES.md` | 英文 | 端到端用法与最佳实践 | 应用开发者 |
|
|
33
|
+
| `../examples/README.md` | 英文 | 示例脚本导航与运行说明 | 新用户 |
|
|
34
|
+
| `PERFORMANCE_GUIDE.md` | 英文 | 搜索与数据库性能指南 | 性能优化工程师 |
|
|
35
|
+
| `Hybrid_Reranking.md` | 英文 | 混合检索与重排设计说明 | 搜索相关性工程师 |
|
|
36
|
+
| `SmartChunking.md` | 英文 | 分块策略说明 | 数据导入/切分开发者 |
|
|
37
|
+
| `MIGRATION_GUIDE.md` | 英文 | 版本迁移说明 | 维护者 |
|
|
38
|
+
| `smartrag_improvement_plan.md` | 中文 | 1-2 天改进执行计划 | 维护者/负责人 |
|
|
39
|
+
| `retrieval_plan.md` | 中文 | RetrievalPlan 契约规范 | SmartBrain/检索接入开发者 |
|
|
40
|
+
| `evidence_pack.md` | 中文 | EvidencePack 契约规范 | SmartBrain/检索接入开发者 |
|
|
41
|
+
| `../test/README.md` | 中文 | 测试文档数据集说明 | QA / 开发者 |
|
|
42
|
+
| `../test/TEST_GUIDE.md` | 中文 | 手工测试脚本与场景说明 | QA / 开发者 |
|
|
43
|
+
| `design.md` | 英文 | 系统设计说明 | 架构/维护者 |
|
|
44
|
+
| `requirements.md` | 英文 | 需求定义 | 产品/架构评审 |
|
|
45
|
+
| `FIX_SUMMARY.md` | 英文 | 阶段性修复总结 | 维护者 |
|
|
46
|
+
| `FIX_SUMMARY_COMPLETE.md` | 英文 | 完整修复报告 | 维护者 |
|
|
47
|
+
| `todo.md` | 英文 | 待办与规划 | 维护者 |
|
|
48
|
+
|
|
49
|
+
## 当前缺口与对齐说明
|
|
50
|
+
|
|
51
|
+
- 部分文档仍使用旧默认值示例(如 OpenAI)。运行时配置以 `../config/smart_rag.yml` 为准。
|
|
52
|
+
- 当前文档语言分布不均:部分仅中文、部分仅英文。后续可按优先级补齐对应翻译版本。
|
|
53
|
+
|
|
54
|
+
## 文档维护建议
|
|
55
|
+
|
|
56
|
+
- API 发生变更时,至少同步更新:
|
|
57
|
+
- `../lib/smart_rag.rb`
|
|
58
|
+
- `API_DOCUMENTATION.md`
|
|
59
|
+
- `USAGE_EXAMPLES.md`
|
|
60
|
+
- `../examples/*.rb`
|
|
61
|
+
- 默认配置调整时,至少同步更新:
|
|
62
|
+
- `../.env.example`
|
|
63
|
+
- `../config/smart_rag.yml`
|
|
64
|
+
- `../README.md`
|
|
65
|
+
- `../README.en.md`
|
data/docs/FIX_SUMMARY.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# SmartRAG 搜索问题修复总结
|
|
2
|
+
|
|
3
|
+
## 修复日期
|
|
4
|
+
2026-01-05
|
|
5
|
+
|
|
6
|
+
## 用户报告的问题
|
|
7
|
+
用户报告:"老人情感"在搜索时会被识别为英文?"
|
|
8
|
+
|
|
9
|
+
## 根本原因分析
|
|
10
|
+
|
|
11
|
+
发现了 **5 个 Bug** 导致搜索失败:
|
|
12
|
+
|
|
13
|
+
## 问题描述
|
|
14
|
+
搜索功能无法返回任何结果,即使数据库中有匹配的中文内容。
|
|
15
|
+
|
|
16
|
+
## 根本原因分析
|
|
17
|
+
|
|
18
|
+
发现了 **4 个 Bug** 导致搜索失败:
|
|
19
|
+
|
|
20
|
+
### Bug 1: 数据库配置名称错误
|
|
21
|
+
**位置**: `/root/smart_rag/db/seeds/text_search_configs.sql` (第 12-14 行)
|
|
22
|
+
|
|
23
|
+
**问题**: PostgreSQL 中 pg_jieba 扩展的配置名称是 `'jiebacfg'`,但种子数据中使用的是 `'jieba'`
|
|
24
|
+
|
|
25
|
+
**影响**: 中文全文搜索时使用错误的分词器配置名,导致搜索失败
|
|
26
|
+
|
|
27
|
+
**修复**:
|
|
28
|
+
```sql
|
|
29
|
+
-- 修改前
|
|
30
|
+
('zh', 'jieba', true),
|
|
31
|
+
|
|
32
|
+
-- 修改后
|
|
33
|
+
('zh', 'jiebacfg', true),
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Bug 2: 语言检测错误
|
|
37
|
+
**位置**: `/root/smart_rag/lib/smart_rag/core/document_processor.rb` (第 463-490 行)
|
|
38
|
+
|
|
39
|
+
**问题**: `extract_html_metadata` 方法没有提取内容用于语言检测,导致所有文档的语言默认为 `'en'`
|
|
40
|
+
|
|
41
|
+
**影响**:
|
|
42
|
+
- `source_documents.language = 'en'`(实际应为 'zh')
|
|
43
|
+
- `section_fts.language = 'en'`(通过触发器继承)
|
|
44
|
+
- 使用英文分词器索引中文内容
|
|
45
|
+
|
|
46
|
+
**修复**: 添加了内容提取逻辑
|
|
47
|
+
```ruby
|
|
48
|
+
# Extract body content for language detection
|
|
49
|
+
body_content = content.gsub(/<script[^>]*>.*?<\/script>/mi, '')
|
|
50
|
+
.gsub(/<style[^>]*>.*?<\/style>/mi, '')
|
|
51
|
+
if body_content =~ /<body[^>]*>(.*?)<\/body>/mi
|
|
52
|
+
metadata[:content] = $1.gsub(/<[^>]+>/, ' ').strip.gsub(/\s+/, ' ')
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Bug 3: 数据库数据不一致
|
|
56
|
+
**位置**: 数据库中的 `source_documents` 和 `section_fts` 表
|
|
57
|
+
|
|
58
|
+
**问题**: 现有数据的 language 字段为 `'en'`,但内容为中文
|
|
59
|
+
|
|
60
|
+
**影响**: 使用英文分词器索引,中文内容无法被正确分词
|
|
61
|
+
|
|
62
|
+
**修复**: 执行数据库修复脚本
|
|
63
|
+
```sql
|
|
64
|
+
-- 更新中文文档的语言
|
|
65
|
+
UPDATE source_documents sd
|
|
66
|
+
SET language = 'zh'
|
|
67
|
+
WHERE sd.id IN (SELECT document_id FROM source_sections WHERE content ~ '[\u4e00-\u9fff]')
|
|
68
|
+
AND (sd.language = 'en' OR sd.language IS NULL OR sd.language = '');
|
|
69
|
+
|
|
70
|
+
-- 重建全文索引
|
|
71
|
+
DELETE FROM section_fts;
|
|
72
|
+
-- 触发器会自动使用正确的语言和分词器重建索引
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Bug 4: 传入错误的数据库连接对象
|
|
76
|
+
**位置**: `/root/smart_rag/lib/smart_rag.rb` (第 289 行)
|
|
77
|
+
|
|
78
|
+
**问题**: 传递给 FulltextManager 的是数据库配置 hash,而不是 Sequel::Database 对象
|
|
79
|
+
|
|
80
|
+
**影响**: `db[:section_fts]` 操作失败,因为 hash 没有 table 方法
|
|
81
|
+
|
|
82
|
+
**修复**:
|
|
83
|
+
```ruby
|
|
84
|
+
# 修改前
|
|
85
|
+
fulltext_manager = ::SmartRAG::Core::FulltextManager.new(@config[:database], @config[:fulltext] || {})
|
|
86
|
+
|
|
87
|
+
# 修改后
|
|
88
|
+
db_connection = ::SmartRAG.db
|
|
89
|
+
fulltext_manager = ::SmartRAG::Core::FulltextManager.new(db_connection, @config[:fulltext] || {})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Bug 5: section_fts 索引数据不完整(**核心问题**)
|
|
93
|
+
**位置**: 数据库中的 `section_fts` 表
|
|
94
|
+
|
|
95
|
+
**问题**:
|
|
96
|
+
- `fts_title` 字段有数据(通过触发器填充)
|
|
97
|
+
- `fts_content` 和 `fts_combined` 字段为空
|
|
98
|
+
|
|
99
|
+
**影响**:
|
|
100
|
+
- 搜索"老人情感"等关键词时无法匹配到内容
|
|
101
|
+
- 因为 `fts_combined` 是空字符串,全文搜索失败
|
|
102
|
+
|
|
103
|
+
**原因**:
|
|
104
|
+
- 触发器只在部分情况下更新 fts_content 和 fts_combined
|
|
105
|
+
- 当通过 `ON CONFLICT` 更新时,fts_content 未被正确设置
|
|
106
|
+
|
|
107
|
+
**修复**: 执行完整的索引重建脚本
|
|
108
|
+
```sql
|
|
109
|
+
-- db/rebuild_fts_complete.sql
|
|
110
|
+
DELETE FROM section_fts;
|
|
111
|
+
INSERT INTO section_fts (section_id, document_id, language)
|
|
112
|
+
SELECT ss.id, ss.document_id, COALESCE(sd.language, 'zh')
|
|
113
|
+
FROM source_sections ss
|
|
114
|
+
JOIN source_documents sd ON sd.id = ss.document_id;
|
|
115
|
+
|
|
116
|
+
-- 触发更新所有 section
|
|
117
|
+
UPDATE source_sections SET updated_at = CURRENT_TIMESTAMP;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**验证**:
|
|
121
|
+
```sql
|
|
122
|
+
-- 重建前:fts_content 和 fts_combined 为空
|
|
123
|
+
-- 重建后:所有字段都有数据
|
|
124
|
+
SELECT COUNT(*) as sections_with_complete_fts
|
|
125
|
+
FROM section_fts
|
|
126
|
+
WHERE fts_combined IS NOT NULL;
|
|
127
|
+
-- 结果:10 个 section 都有完整的索引
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 修复文件清单
|
|
131
|
+
|
|
132
|
+
### 1. 配置文件
|
|
133
|
+
- ✅ `/root/smart_rag/db/seeds/text_search_configs.sql`
|
|
134
|
+
- 将 `'jieba'` 改为 `'jiebacfg'`
|
|
135
|
+
|
|
136
|
+
### 2. 代码文件
|
|
137
|
+
- ✅ `/root/smart_rag/lib/smart_rag/core/document_processor.rb`
|
|
138
|
+
- 添加 HTML 内容提取逻辑用于语言检测
|
|
139
|
+
- ✅ `/root/smart_rag/lib/smart_rag/core/fulltext_manager.rb`
|
|
140
|
+
- 添加调试日志输出 SQL 和 tsquery
|
|
141
|
+
|
|
142
|
+
### 3. 数据库修复
|
|
143
|
+
- ✅ `/root/smart_rag/db/fix_search_issues.sql`
|
|
144
|
+
- 更新 text_search_configs 配置
|
|
145
|
+
- 更新 source_documents 语言
|
|
146
|
+
- 重建 section_fts 全文索引
|
|
147
|
+
|
|
148
|
+
### 4. 核心文件
|
|
149
|
+
- ✅ `/root/smart_rag/lib/smart_rag.rb`
|
|
150
|
+
- 修复传递给 FulltextManager 的数据库连接对象
|
|
151
|
+
|
|
152
|
+
## 验证结果
|
|
153
|
+
|
|
154
|
+
### 修复前(Bug 5 未修复)
|
|
155
|
+
搜索"老人情感"返回 0 个结果,即使数据库中包含相关内容。
|
|
156
|
+
|
|
157
|
+
### 修复后(Bug 5 已修复)
|
|
158
|
+
|
|
159
|
+
**测试 1: 搜索"老人情感"(全文搜索)**
|
|
160
|
+
```bash
|
|
161
|
+
Results: 3
|
|
162
|
+
1. 宠物比子女还亲 小动物承担了老人情感需求 (Part 2)
|
|
163
|
+
2. 宠物比子女还亲 小动物承担了老人情感需求
|
|
164
|
+
3. 相关文章
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**测试 2: 混合搜索**
|
|
168
|
+
```bash
|
|
169
|
+
Results: 3
|
|
170
|
+
1. 宠物比子女还亲 小动物承担了老人情感需求 (Part 2) (score: 0.005)
|
|
171
|
+
,这些对于老年人来说,都是负性因素。”
|
|
172
|
+
|
|
173
|
+
人虽然老了,但是他们对情感的需求还在,他们希望孩子能常陪在自己的身边...
|
|
174
|
+
|
|
175
|
+
2. 宠物比子女还亲 小动物承担了老人情感需求 (score: 0.005)
|
|
176
|
+
**作者:贾晓宏** **来源:北京晚报**
|
|
177
|
+
发布时间:2016-08-19
|
|
178
|
+
字号:\+-14
|
|
179
|
+
浏览次数:
|
|
180
|
+
**小狗病逝,老人抑郁了**
|
|
181
|
+
...
|
|
182
|
+
|
|
183
|
+
3. 相关文章 (score: 0.005)
|
|
184
|
+
* [2020年北大六院发表SCI论文一览](...)
|
|
185
|
+
* [北京大学第六医院精神科临床进修班招生简章](...)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**数据库验证**:
|
|
189
|
+
```sql
|
|
190
|
+
SELECT COUNT(*) as sections_with_complete_fts
|
|
191
|
+
FROM section_fts
|
|
192
|
+
WHERE fts_combined IS NOT NULL;
|
|
193
|
+
-- 结果:10 个 section 都有完整的索引
|
|
194
|
+
|
|
195
|
+
-- 验证中文分词
|
|
196
|
+
SELECT to_tsvector('jiebacfg', '老人情感');
|
|
197
|
+
-- 结果:'老人':2 '情感':3
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 技术细节
|
|
201
|
+
|
|
202
|
+
### 全文搜索查询
|
|
203
|
+
```sql
|
|
204
|
+
SELECT "section_fts"."section_id", "section_fts"."language",
|
|
205
|
+
ts_rank("section_fts"."fts_combined",
|
|
206
|
+
plainto_tsquery('jiebacfg', '小动物承担了老人情感需求')) AS "rank_score",
|
|
207
|
+
ts_headline("source_sections"."content",
|
|
208
|
+
plainto_tsquery('jiebacfg', '小动物承担了老人情感需求'),
|
|
209
|
+
'MaxWords=50, MinWords=15, MaxFragments=3') AS "highlight"
|
|
210
|
+
FROM "section_fts"
|
|
211
|
+
INNER JOIN "source_sections" ON ("source_sections"."id" = "section_fts"."section_id")
|
|
212
|
+
WHERE (section_fts.fts_combined @@ plainto_tsquery('jiebacfg', '小动物承担了老人情感需求'))
|
|
213
|
+
ORDER BY "rank_score" DESC
|
|
214
|
+
LIMIT 10
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 中文分词测试
|
|
218
|
+
```sql
|
|
219
|
+
-- 使用 jiebacfg 配置
|
|
220
|
+
SELECT to_tsvector('jiebacfg', '小动物承担了老人情感需求');
|
|
221
|
+
-- 结果: '动物':2 '情感':6 '承担':3 '老人':5 '需求':7
|
|
222
|
+
|
|
223
|
+
-- 构建查询
|
|
224
|
+
SELECT plainto_tsquery('jiebacfg', '小动物承担了老人情感需求');
|
|
225
|
+
-- 结果: '动物' & '承担' & '老人' & '情感' & '需求'
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## 后续建议
|
|
229
|
+
|
|
230
|
+
### 1. 添加单元测试
|
|
231
|
+
建议为以下功能添加单元测试:
|
|
232
|
+
- 语言检测功能
|
|
233
|
+
- 全文搜索构建
|
|
234
|
+
- 数据库触发器逻辑
|
|
235
|
+
|
|
236
|
+
### 2. 添加数据库迁移
|
|
237
|
+
将修复脚本转换为正式的数据库迁移文件,以便在部署时自动执行
|
|
238
|
+
|
|
239
|
+
### 3. 改进错误处理
|
|
240
|
+
- 添加更好的错误提示
|
|
241
|
+
- 在分词器不可用时提供降级方案
|
|
242
|
+
|
|
243
|
+
### 4. 性能优化
|
|
244
|
+
- 为中文内容添加专门的 GIN 索引
|
|
245
|
+
- 考虑使用分区表按语言分区
|
|
246
|
+
|
|
247
|
+
## 结论
|
|
248
|
+
|
|
249
|
+
所有 4 个 Bug 已成功修复,中文全文搜索功能现在正常工作。用户可以搜索中文内容并获得准确的结果。
|
|
250
|
+
|
|
251
|
+
修复涉及的系统:
|
|
252
|
+
- ✅ 数据库配置和迁移
|
|
253
|
+
- ✅ 文档处理和语言检测
|
|
254
|
+
- ✅ 全文搜索功能
|
|
255
|
+
- ✅ 混合搜索功能
|
|
256
|
+
- ✅ 数据库连接管理
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# SmartRAG 搜索问题修复总结
|
|
2
|
+
|
|
3
|
+
## 修复日期
|
|
4
|
+
2026-01-05
|
|
5
|
+
|
|
6
|
+
## 用户报告的问题
|
|
7
|
+
用户报告:"老人情感"在搜索时会被识别为英文?
|
|
8
|
+
|
|
9
|
+
## 根本原因分析
|
|
10
|
+
|
|
11
|
+
发现了 **5 个 Bug** 导致搜索失败:
|
|
12
|
+
|
|
13
|
+
### Bug 1: 数据库配置名称错误
|
|
14
|
+
**位置**: `/root/smart_rag/db/seeds/text_search_configs.sql` (第 12-14 行)
|
|
15
|
+
|
|
16
|
+
**问题**: PostgreSQL 中 pg_jieba 扩展的配置名称是 `'jiebacfg'`,但种子数据中使用的是 `'jieba'`
|
|
17
|
+
|
|
18
|
+
**影响**: 中文全文搜索时使用错误的分词器配置名,导致搜索失败
|
|
19
|
+
|
|
20
|
+
**修复**:
|
|
21
|
+
```sql
|
|
22
|
+
-- 修改前
|
|
23
|
+
('zh', 'jieba', true),
|
|
24
|
+
|
|
25
|
+
-- 修改后
|
|
26
|
+
('zh', 'jiebacfg', true),
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Bug 2: 语言检测错误
|
|
30
|
+
**位置**: `/root/smart_rag/lib/smart_rag/core/document_processor.rb` (第 463-490 行)
|
|
31
|
+
|
|
32
|
+
**问题**: `extract_html_metadata` 方法没有提取内容用于语言检测,导致所有文档的语言默认为 `'en'`
|
|
33
|
+
|
|
34
|
+
**影响**:
|
|
35
|
+
- `source_documents.language = 'en'`(实际应为 'zh')
|
|
36
|
+
- `section_fts.language = 'en'`(通过触发器继承)
|
|
37
|
+
- 使用英文分词器索引中文内容
|
|
38
|
+
|
|
39
|
+
**修复**: 添加了内容提取逻辑
|
|
40
|
+
```ruby
|
|
41
|
+
# Extract body content for language detection
|
|
42
|
+
body_content = content.gsub(/<script[^>]*>.*?<\/script>/mi, '')
|
|
43
|
+
.gsub(/<style[^>]*>.*?<\/style>/mi, '')
|
|
44
|
+
if body_content =~ /<body[^>]*>(.*?)<\/body>/mi
|
|
45
|
+
metadata[:content] = $1.gsub(/<[^>]+>/, ' ').strip.gsub(/\s+/, ' ')
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Bug 3: 数据库数据不一致
|
|
49
|
+
**位置**: 数据库中的 `source_documents` 和 `section_fts` 表
|
|
50
|
+
|
|
51
|
+
**问题**: 现有数据的 language 字段为 `'en'`,但内容为中文
|
|
52
|
+
|
|
53
|
+
**影响**: 使用英文分词器索引,中文内容无法被正确分词
|
|
54
|
+
|
|
55
|
+
**修复**: 执行数据库修复脚本
|
|
56
|
+
```sql
|
|
57
|
+
-- 更新中文文档的语言
|
|
58
|
+
UPDATE source_documents sd
|
|
59
|
+
SET language = 'zh'
|
|
60
|
+
WHERE sd.id IN (SELECT document_id FROM source_sections WHERE content ~ '[\u4e00-\u9fff]')
|
|
61
|
+
AND (sd.language = 'en' OR sd.language IS NULL OR sd.language = '');
|
|
62
|
+
|
|
63
|
+
-- 重建全文索引
|
|
64
|
+
DELETE FROM section_fts;
|
|
65
|
+
-- 触发器会自动使用正确的语言和分词器重建索引
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Bug 4: 传入错误的数据库连接对象
|
|
69
|
+
**位置**: `/root/smart_rag/lib/smart_rag.rb` (第 289 行)
|
|
70
|
+
|
|
71
|
+
**问题**: 传递给 FulltextManager 的是数据库配置 hash,而不是 Sequel::Database 对象
|
|
72
|
+
|
|
73
|
+
**影响**: `db[:section_fts]` 操作失败,因为 hash 没有 table 方法
|
|
74
|
+
|
|
75
|
+
**修复**:
|
|
76
|
+
```ruby
|
|
77
|
+
# 修改前
|
|
78
|
+
fulltext_manager = ::SmartRAG::Core::FulltextManager.new(@config[:database], @config[:fulltext] || {})
|
|
79
|
+
|
|
80
|
+
# 修改后
|
|
81
|
+
db_connection = ::SmartRAG.db
|
|
82
|
+
fulltext_manager = ::SmartRAG::Core::FulltextManager.new(db_connection, @config[:fulltext] || {})
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Bug 5: section_fts 索引数据不完整(**核心问题**)
|
|
86
|
+
**位置**: 数据库中的 `section_fts` 表
|
|
87
|
+
|
|
88
|
+
**问题**:
|
|
89
|
+
- `fts_title` 字段有数据(通过触发器填充)
|
|
90
|
+
- `fts_content` 和 `fts_combined` 字段为空
|
|
91
|
+
|
|
92
|
+
**影响**:
|
|
93
|
+
- 搜索"老人情感"等关键词时无法匹配到内容
|
|
94
|
+
- 因为 `fts_combined` 是空字符串,全文搜索失败
|
|
95
|
+
|
|
96
|
+
**原因**:
|
|
97
|
+
- 触发器在部分情况下只更新了 `fts_title`
|
|
98
|
+
- 当通过 `ON CONFLICT` 更新时,`fts_content` 未被正确设置
|
|
99
|
+
|
|
100
|
+
**修复**: 执行完整的索引重建脚本
|
|
101
|
+
```sql
|
|
102
|
+
-- db/rebuild_fts_complete.sql
|
|
103
|
+
-- 1. 删除所有 fts 数据
|
|
104
|
+
DELETE FROM section_fts;
|
|
105
|
+
|
|
106
|
+
-- 2. 重新插入所有 section 基础信息
|
|
107
|
+
INSERT INTO section_fts (section_id, document_id, language)
|
|
108
|
+
SELECT
|
|
109
|
+
ss.id,
|
|
110
|
+
ss.document_id,
|
|
111
|
+
COALESCE(sd.language, 'zh') as language
|
|
112
|
+
FROM source_sections ss
|
|
113
|
+
JOIN source_documents sd ON sd.id = ss.document_id;
|
|
114
|
+
|
|
115
|
+
-- 3. 触发更新所有 section 以重建 fts 字段
|
|
116
|
+
UPDATE source_sections SET updated_at = CURRENT_TIMESTAMP;
|
|
117
|
+
|
|
118
|
+
-- 验证
|
|
119
|
+
SELECT COUNT(*) as sections_with_complete_fts
|
|
120
|
+
FROM section_fts
|
|
121
|
+
WHERE fts_combined IS NOT NULL;
|
|
122
|
+
-- 结果:10 个 section 都有完整的索引
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 修复文件清单
|
|
126
|
+
|
|
127
|
+
### 1. 配置文件
|
|
128
|
+
- ✅ `/root/smart_rag/db/seeds/text_search_configs.sql`
|
|
129
|
+
- 将 `'jieba'` 改为 `'jiebacfg'`
|
|
130
|
+
|
|
131
|
+
### 2. 代码文件
|
|
132
|
+
- ✅ `/root/smart_rag/lib/smart_rag/core/document_processor.rb`
|
|
133
|
+
- 添加 HTML 内容提取逻辑用于语言检测
|
|
134
|
+
- ✅ `/root/smart_rag/lib/smart_rag/core/fulltext_manager.rb`
|
|
135
|
+
- 添加调试日志输出 SQL 和 tsquery
|
|
136
|
+
- ✅ `/root/smart_rag/lib/smart_rag/parsers/query_parser.rb`
|
|
137
|
+
- 添加语言检测的调试日志
|
|
138
|
+
|
|
139
|
+
### 3. 数据库修复
|
|
140
|
+
- ✅ `/root/smart_rag/db/fix_search_issues.sql`(第一次修复)
|
|
141
|
+
- 更新 text_search_configs 配置
|
|
142
|
+
- 更新 source_documents 语言
|
|
143
|
+
- 删除并重新插入 section_fts 数据
|
|
144
|
+
- ✅ `/root/smart_rag/db/rebuild_fts_complete.sql`(第二次修复)
|
|
145
|
+
- 完整重建所有 section_fts 索引
|
|
146
|
+
- 确保 fts_content 和 fts_combined 正确填充
|
|
147
|
+
- 触发所有 section 更新以重建 fts 向量
|
|
148
|
+
|
|
149
|
+
### 4. 核心文件
|
|
150
|
+
- ✅ `/root/smart_rag/lib/smart_rag.rb`
|
|
151
|
+
- 修复传递给 FulltextManager 的数据库连接对象
|
|
152
|
+
|
|
153
|
+
## 验证结果
|
|
154
|
+
|
|
155
|
+
### 修复前(Bug 5 未修复)
|
|
156
|
+
搜索"老人情感"返回 0 个结果,即使数据库中包含相关内容。
|
|
157
|
+
|
|
158
|
+
### 修复后(Bug 5 已修复)
|
|
159
|
+
|
|
160
|
+
**测试 1: 搜索"老人情感"(全文搜索)**
|
|
161
|
+
```bash
|
|
162
|
+
Results: 3
|
|
163
|
+
1. 宠物比子女还亲 小动物承担了老人情感需求 (Part 2)
|
|
164
|
+
2. 宠物比子女还亲 小动物承担了老人情感需求
|
|
165
|
+
3. 相关文章
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**测试 2: 混合搜索**
|
|
169
|
+
```bash
|
|
170
|
+
Results: 3
|
|
171
|
+
1. 宠物比子女还亲 小动物承担了老人情感需求 (Part 2) (score: 0.005)
|
|
172
|
+
,这些对于老年人来说,都是负性因素。
|
|
173
|
+
|
|
174
|
+
人虽然老了,但是他们对情感的需求还在...
|
|
175
|
+
|
|
176
|
+
2. 宠物比子女还亲 小动物承担了老人情感需求 (score: 0.005)
|
|
177
|
+
**作者:贾晓宏** **来源:北京晚报**
|
|
178
|
+
发布时间:2016-08-19
|
|
179
|
+
字号:\+-14
|
|
180
|
+
浏览次数:
|
|
181
|
+
|
|
182
|
+
**小狗病逝,老人抑郁了**
|
|
183
|
+
|
|
184
|
+
3. 相关文章 (score: 0.005)
|
|
185
|
+
* [2020年北大六院发表SCI论文一览](...)
|
|
186
|
+
* [北京大学第六医院精神科临床进修班招生简章](...)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**数据库验证**:
|
|
190
|
+
```sql
|
|
191
|
+
-- 验证所有 section 都有完整索引
|
|
192
|
+
SELECT COUNT(*) as sections_with_complete_fts
|
|
193
|
+
FROM section_fts
|
|
194
|
+
WHERE fts_combined IS NOT NULL;
|
|
195
|
+
-- 结果:10 个 section 都有完整的索引
|
|
196
|
+
|
|
197
|
+
-- 验证中文分词
|
|
198
|
+
SELECT to_tsvector('jiebacfg', '老人情感');
|
|
199
|
+
-- 结果:'老人':2 '情感':3
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 技术细节
|
|
203
|
+
|
|
204
|
+
### 中文全文搜索配置
|
|
205
|
+
```sql
|
|
206
|
+
-- 使用 jiebacfg 配置
|
|
207
|
+
SELECT plainto_tsquery('jiebacfg', '老人情感');
|
|
208
|
+
-- 结果:'老人' & '情感'
|
|
209
|
+
|
|
210
|
+
-- 实际分词结果
|
|
211
|
+
SELECT to_tsvector('jiebacfg', '老人情感');
|
|
212
|
+
-- 结果:'老人':2 '情感':3
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 搜索查询示例
|
|
216
|
+
```sql
|
|
217
|
+
-- 完整的全文搜索查询
|
|
218
|
+
SELECT ss.section_title, ssf.language
|
|
219
|
+
FROM section_fts ssf
|
|
220
|
+
JOIN source_sections ss ON ss.id = ssf.section_id
|
|
221
|
+
WHERE ssf.fts_combined @@ plainto_tsquery('jiebacfg', '老人情感')
|
|
222
|
+
AND ssf.language = 'zh'
|
|
223
|
+
ORDER BY ts_rank(ssf.fts_combined, plainto_tsquery('jiebacfg', '老人情感')) DESC
|
|
224
|
+
LIMIT 5;
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 数据库触发器
|
|
228
|
+
触发器在 section 插入或更新时自动维护全文索引:
|
|
229
|
+
1. 从文档获取语言
|
|
230
|
+
2. 获取对应的分词器配置(jiebacfg for zh)
|
|
231
|
+
3. 生成 fts_title(权重 A)、fts_content(权重 B)、fts_combined
|
|
232
|
+
4. 更新 section_fts 表
|
|
233
|
+
|
|
234
|
+
## 后续建议
|
|
235
|
+
|
|
236
|
+
### 1. 添加单元测试
|
|
237
|
+
建议为以下功能添加单元测试:
|
|
238
|
+
- 语言检测功能
|
|
239
|
+
- 全文搜索构建
|
|
240
|
+
- 数据库触发器逻辑
|
|
241
|
+
- 索引重建逻辑
|
|
242
|
+
|
|
243
|
+
### 2. 添加数据库迁移
|
|
244
|
+
将修复脚本转换为正式的数据库迁移文件,以便在部署时自动执行
|
|
245
|
+
|
|
246
|
+
### 3. 改进触发器逻辑
|
|
247
|
+
- 确保 `ON CONFLICT` 更新时正确设置所有 fts 字段
|
|
248
|
+
- 添加触发器失败的错误处理和日志记录
|
|
249
|
+
|
|
250
|
+
### 4. 添加索引健康检查
|
|
251
|
+
实现定期检查索引完整性的功能:
|
|
252
|
+
```sql
|
|
253
|
+
-- 查找空索引的 section
|
|
254
|
+
SELECT section_id
|
|
255
|
+
FROM section_fts
|
|
256
|
+
WHERE fts_combined IS NULL OR fts_combined = '';
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## 结论
|
|
260
|
+
|
|
261
|
+
所有 5 个 Bug 已成功修复,中文全文搜索功能现在正常工作。
|
|
262
|
+
|
|
263
|
+
**关键修复**:Bug 5 是用户报告问题的根本原因。通过完整重建 `section_fts` 表的全文索引,确保了 `fts_content` 和 `fts_combined` 字段都被正确填充,从而使中文搜索能够正常工作。
|
|
264
|
+
|
|
265
|
+
修复涉及的系统:
|
|
266
|
+
- ✅ 数据库配置和迁移
|
|
267
|
+
- ✅ 文档处理和语言检测
|
|
268
|
+
- ✅ 全文搜索功能
|
|
269
|
+
- ✅ 混合搜索功能
|
|
270
|
+
- ✅ 数据库连接管理
|
|
271
|
+
- ✅ 全文索引完整性和重建
|
|
272
|
+
|
|
273
|
+
用户现在可以搜索中文内容并获得准确的结果。
|