MeiliSearch 搜索运维指南
📋 概述
本文档介绍 CmsKit 搜索系统的运维操作,包括索引初始化、增量更新、异常处理等。
🏗️ 架构说明
索引结构
articles_Normal - 普通文章索引
articles_AiNews - AI 新闻文章索引
shortmsgs - 沸点/短文索引
数据同步流程
全量同步(启动时)
↓
增量同步(每小时)
↓
实时同步(CAP 事件触发)
🚀 运维操作
1. 索引初始化
方式一:后台任务自动执行
系统启动时会自动执行 MeiliSearchIndexJob 后台任务:
# 查看日志
dotnet run --urls=http://localhost:5000
# 日志输出:
# "开始执行 MeiliSearch 索引初始化任务"
# "文章索引初始化完成"
# "沸点索引初始化完成"
方式二:API 手动触发
# 初始化所有文章索引
curl -X GET http://localhost:5000/api/cms/article/init-all-articles
# 初始化所有沸点索引
curl -X GET http://localhost:5000/api/cms/short_msg/init-all-shortmsgs
方式三:定时任务
在 FreeKit.Job.Host 中配置的定时任务:
// 每天凌晨 2 点执行全量同步
"0 2 * * *"
2. 增量同步
系统默认每小时自动执行一次增量同步:
- 执行时间: 每小时整点
- 同步范围: 过去 1 小时内更新的内容
- 触发条件: 系统运行中自动执行
手动触发增量同步:
# 等待定时任务自动执行,或重启服务立即执行
3. 实时同步
通过 CAP 事件总线实现:
// 文章创建/更新事件
[CapSubscribe("cms.article.created")]
public async Task HandleArticleCreated(Article article) {
await _articleSearchService.IndexOrUpdateArticleAsync(article, article.ArticleCategory);
}
// 文章删除事件
[CapSubscribe("cms.article.deleted")]
public async Task HandleArticleDeleted(Guid articleId) {
// 删除索引
}
🔧 配置优化
1. 同义词配置
在 MeiliSearchConfigService 中配置同义词:
var synonyms = new Dictionary<string, IEnumerable<string>>
{
{ "ai", new[] { "人工智能", "AI", "machine learning" } },
{ "机器学习", new[] { "ML", "machine learning", "深度学习" } },
{ ".NET", new[] { "dotnet", "csharp", "C#" } }
};
2. 拼写纠错配置
var typoTolerance = new TypoTolerance
{
Enabled = true,
MinWordSizeForTypos = new TypoSize
{
OneTypo = 5, // 5 个字符以上的词允许 1 个拼写错误
TwoTypos = 9 // 9 个字符以上的词允许 2 个拼写错误
}
};
3. 可搜索字段权重
// 字段按权重排序
await index.UpdateSearchableAttributesAsync(new[] { "title", "content", "tags" });
// title > content > tags
📊 监控与告警
1. 索引状态检查
# 查看索引统计
curl -X GET 'http://localhost:7700/indexes/articles_Normal/stats' \
-H 'Authorization: Bearer your-api-key'
# 返回示例:
{
"numberOfDocuments": 1250,
"fieldDistribution": {
"title": 1250,
"content": 1250,
"tags": 1200
}
}
2. 搜索性能监控
# 慢查询日志(>100ms)
# 在 MeiliSearch 配置中启用日志
3. 健康检查
// 添加健康检查
services.AddHealthChecks()
.AddCheck<MeiliSearchHealthCheck>("meilisearch");
⚠️ 异常处理
1. 索引损坏
症状: 搜索返回空结果或报错
解决方案:
# 1. 删除损坏的索引
curl -X DELETE 'http://localhost:7700/indexes/articles_Normal' \
-H 'Authorization: Bearer your-api-key'
# 2. 重新初始化
curl -X GET http://localhost:5000/api/cms/article/init-all-articles
2. 数据不一致
症状: 数据库有数据但搜索不到
解决方案:
# 执行全量同步
curl -X GET http://localhost:5000/api/cms/article/init-all-articles
curl -X GET http://localhost:5000/api/cms/short_msg/init-all-shortmsgs
3. 搜索性能下降
症状: 搜索响应时间 > 500ms
解决方案:
- 检查索引大小(>100 万条考虑分片)
- 优化可搜索字段(减少字段数量)
- 启用拼写纠错缓存
- 增加 MeiliSearch 实例
📝 最佳实践
1. 索引更新策略
- 全量同步: 每天凌晨 2 点(低峰期)
- 增量同步: 每小时执行
- 实时同步: CAP 事件触发
2. 搜索优化
- 标题权重 > 内容权重 > 标签权重
- 启用同义词扩展
- 合理配置拼写纠错阈值
- 对热门搜索结果缓存(10 分钟)
3. 监控指标
- 索引文档数量
- 搜索响应时间(P95 < 100ms)
- 搜索无结果率
- 热门搜索词 TOP 50
🔍 调试技巧
1. 查看原始搜索结果
// 在控制器中返回 MeiliSearch 原始结果
var searchResult = await _msClient.Index("articles_Normal")
.SearchAsync<ArticleDocument>(keyword, new SearchQuery { Limit = 20 });
2. 测试同义词
# 搜索 "ai" 应该返回包含 "人工智能" 的结果
curl -X POST 'http://localhost:7700/indexes/articles_Normal/search' \
-H 'Authorization: Bearer your-api-key' \
-H 'Content-Type: application/json' \
--data-binary '{"q": "ai", "limit": 10}'
3. 分析搜索性能
# 使用 MeiliSearch 的查询分析
curl -X POST 'http://localhost:7700/indexes/articles_Normal/search' \
-H 'Authorization: Bearer your-api-key' \
-H 'Content-Type: application/json' \
--data-binary '{"q": "keyword", "showRankingScore": true}'
📚 相关文档
🆘 常见问题
Q: 为什么搜索不到刚发布的文章?
A: 检查增量同步任务是否正常运行,或等待下一次实时同步(CAP 事件触发)。
Q: 同义词不生效?
A: 同义词配置在索引初始化时应用,需要重新初始化索引或手动更新同义词配置。
Q: 如何调整搜索排序?
A: 修改 MeiliSearchConfigService 中的排名规则配置。
最后更新: 2026-03-30