feat: 初始化知识库系统项目
- 实现基于 Laravel 11 和 Filament 3.X 的文档管理系统 - 添加用户认证和分组管理功能 - 实现文档上传、分类和权限控制 - 集成 Word 文档自动转换为 Markdown - 集成 Meilisearch 全文搜索引擎 - 实现文档在线预览功能 - 添加安全日志和审计功能 - 完整的简体中文界面 - 包含完整的项目文档和部署指南 技术栈: - Laravel 11.x - Filament 3.X - Meilisearch 1.5+ - Pandoc 文档转换 - Redis 队列系统 - Pest PHP 测试框架
This commit is contained in:
192
docs/DOCUMENT_SEARCH_GUIDE.md
Normal file
192
docs/DOCUMENT_SEARCH_GUIDE.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# 文档搜索功能指南
|
||||
|
||||
## 概述
|
||||
|
||||
文档搜索功能使用 Laravel Scout 和 Meilisearch 提供强大的全文搜索能力。系统会自动将转换完成的文档索引到 Meilisearch,用户可以通过关键词快速检索文档内容。
|
||||
|
||||
## 核心组件
|
||||
|
||||
### DocumentSearchService
|
||||
|
||||
文档搜索服务类,提供以下功能:
|
||||
|
||||
1. **search()** - 执行全文搜索
|
||||
- 搜索文档标题、描述和 Markdown 内容
|
||||
- 支持额外的筛选条件(类型、分组、上传者)
|
||||
- 自动应用用户权限过滤
|
||||
|
||||
2. **filterByUserPermissions()** - 权限过滤
|
||||
- 确保用户只能看到有权限访问的文档
|
||||
- 全局文档对所有用户可见
|
||||
- 专用文档只对所属分组的用户可见
|
||||
|
||||
3. **prepareSearchableData()** - 准备索引数据
|
||||
- 包含完整的 Markdown 内容用于搜索
|
||||
- 包含文档元数据(标题、描述、类型、分组等)
|
||||
|
||||
4. **indexDocument()** - 索引文档
|
||||
- 将文档添加到 Meilisearch 索引
|
||||
- 只索引转换完成的文档
|
||||
|
||||
5. **updateDocumentIndex()** - 更新索引
|
||||
- 更新已索引文档的信息
|
||||
- 如果文档不应被索引,则移除索引
|
||||
|
||||
6. **removeDocumentFromIndex()** - 移除索引
|
||||
- 从 Meilisearch 中删除文档索引
|
||||
|
||||
### DocumentObserver
|
||||
|
||||
文档观察者,自动管理文档的搜索索引:
|
||||
|
||||
- **created** - 文档创建时不立即索引(等待转换完成)
|
||||
- **updated** - 文档更新时检查转换状态并更新索引
|
||||
- 当 conversion_status 变为 'completed' 时自动索引
|
||||
- 当其他重要字段更新时也更新索引
|
||||
- **deleted** - 文档删除时移除索引
|
||||
- **restored** - 文档恢复时重新索引
|
||||
- **forceDeleted** - 强制删除时移除索引
|
||||
|
||||
## 工作流程
|
||||
|
||||
### 文档索引流程
|
||||
|
||||
1. 用户上传 Word 文档
|
||||
2. 文档保存到数据库,conversion_status 设置为 'pending'
|
||||
3. 转换任务加入队列
|
||||
4. 转换完成后,updateDocumentMarkdown() 将 conversion_status 更新为 'completed'
|
||||
5. DocumentObserver 监听到 updated 事件
|
||||
6. 自动调用 DocumentSearchService::indexDocument() 创建索引
|
||||
7. 文档可以被搜索
|
||||
|
||||
### 搜索流程
|
||||
|
||||
1. 用户输入搜索关键词
|
||||
2. 调用 DocumentSearchService::search()
|
||||
3. 使用 Scout 在 Meilisearch 中搜索
|
||||
4. 应用额外的筛选条件
|
||||
5. 使用 filterByUserPermissions() 过滤结果
|
||||
6. 返回用户有权限访问的文档列表
|
||||
|
||||
## 配置
|
||||
|
||||
### Meilisearch 配置
|
||||
|
||||
在 `config/scout.php` 中配置:
|
||||
|
||||
```php
|
||||
'meilisearch' => [
|
||||
'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),
|
||||
'key' => env('MEILISEARCH_KEY'),
|
||||
'index-settings' => [
|
||||
'documents' => [
|
||||
'filterableAttributes' => ['type', 'group_id', 'uploaded_by', 'conversion_status'],
|
||||
'sortableAttributes' => ['created_at', 'title', 'updated_at'],
|
||||
'searchableAttributes' => ['title', 'description', 'markdown_content'],
|
||||
],
|
||||
],
|
||||
],
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
|
||||
在 `.env` 文件中配置:
|
||||
|
||||
```env
|
||||
SCOUT_DRIVER=meilisearch
|
||||
MEILISEARCH_HOST=http://127.0.0.1:7700
|
||||
MEILISEARCH_KEY=your-master-key
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基本搜索
|
||||
|
||||
```php
|
||||
use App\Services\DocumentSearchService;
|
||||
|
||||
$searchService = app(DocumentSearchService::class);
|
||||
$user = auth()->user();
|
||||
|
||||
// 搜索关键词
|
||||
$results = $searchService->search('Laravel', $user);
|
||||
|
||||
// 带筛选条件的搜索
|
||||
$results = $searchService->search('Laravel', $user, [
|
||||
'type' => 'global',
|
||||
'group_id' => 1,
|
||||
]);
|
||||
```
|
||||
|
||||
### 手动索引管理
|
||||
|
||||
```php
|
||||
use App\Services\DocumentSearchService;
|
||||
use App\Models\Document;
|
||||
|
||||
$searchService = app(DocumentSearchService::class);
|
||||
$document = Document::find(1);
|
||||
|
||||
// 索引文档
|
||||
$searchService->indexDocument($document);
|
||||
|
||||
// 更新索引
|
||||
$searchService->updateDocumentIndex($document);
|
||||
|
||||
// 移除索引
|
||||
$searchService->removeDocumentFromIndex($document);
|
||||
```
|
||||
|
||||
### 批量重建索引
|
||||
|
||||
```php
|
||||
// 重建所有文档的索引
|
||||
php artisan scout:import "App\Models\Document"
|
||||
|
||||
// 清空索引
|
||||
php artisan scout:flush "App\Models\Document"
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
所有索引操作都包含错误处理:
|
||||
|
||||
- 索引失败不会影响文档的正常保存和使用
|
||||
- 所有错误都会记录到日志中
|
||||
- 搜索失败时返回空集合
|
||||
|
||||
## 性能考虑
|
||||
|
||||
1. **异步索引** - 文档转换和索引都在队列中异步处理
|
||||
2. **权限过滤** - 在应用层过滤搜索结果,确保数据安全
|
||||
3. **缓存策略** - 可以缓存热门搜索结果(待实现)
|
||||
4. **分页** - 搜索结果应该分页显示(在前端实现)
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 文档无法被搜索
|
||||
|
||||
1. 检查 conversion_status 是否为 'completed'
|
||||
2. 检查 Meilisearch 服务是否运行
|
||||
3. 检查文档是否已索引:`php artisan scout:import "App\Models\Document"`
|
||||
4. 查看日志文件中的错误信息
|
||||
|
||||
### Meilisearch 连接失败
|
||||
|
||||
1. 确认 Meilisearch 服务正在运行
|
||||
2. 检查 .env 中的 MEILISEARCH_HOST 和 MEILISEARCH_KEY
|
||||
3. 测试连接:`curl http://localhost:7700/health`
|
||||
|
||||
### 搜索结果为空
|
||||
|
||||
1. 确认文档已完成转换
|
||||
2. 确认用户有权限访问文档
|
||||
3. 检查搜索关键词是否正确
|
||||
4. 查看 Meilisearch 日志
|
||||
|
||||
## 下一步
|
||||
|
||||
- 实现搜索页面 UI(任务 25)
|
||||
- 添加搜索结果高亮显示
|
||||
- 实现搜索建议和自动补全
|
||||
- 添加高级搜索语法支持
|
||||
Reference in New Issue
Block a user