Files
KnowledgeBase/docs/DOCUMENT_SEARCH_GUIDE.md
Knowledge Base System acf549c43c feat: 初始化知识库系统项目
- 实现基于 Laravel 11 和 Filament 3.X 的文档管理系统
- 添加用户认证和分组管理功能
- 实现文档上传、分类和权限控制
- 集成 Word 文档自动转换为 Markdown
- 集成 Meilisearch 全文搜索引擎
- 实现文档在线预览功能
- 添加安全日志和审计功能
- 完整的简体中文界面
- 包含完整的项目文档和部署指南

技术栈:
- Laravel 11.x
- Filament 3.X
- Meilisearch 1.5+
- Pandoc 文档转换
- Redis 队列系统
- Pest PHP 测试框架
2025-12-05 14:44:44 +08:00

5.1 KiB
Raw Blame History

文档搜索功能指南

概述

文档搜索功能使用 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 中配置:

'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 文件中配置:

SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=your-master-key

使用示例

基本搜索

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,
]);

手动索引管理

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 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
  • 添加搜索结果高亮显示
  • 实现搜索建议和自动补全
  • 添加高级搜索语法支持