CMS 迁移后搜索结果为空,多半是搜索索引表或独立索引服务没有随数据一起迁移(或迁移后没有重建),代码不是主要问题。先确认站点使用哪种搜索后端(数据库 LIKE 查询、MySQL 全文索引、Elasticsearch、Sphinx、Meilisearch),再按对应方式执行一次全量重建索引,基本都能修好。
搜索结果为空,先怎么定位问题?
结论:按「先确认搜索后端,再比对数据表行数,最后检查缓存和域名」三步定位,10 分钟内就能判断问题是索引没建,还是查询条件被过滤。
第一步,确认搜索后端。打开 CMS 的搜索配置文件或后台搜索设置页,看使用的是数据库查询、全文索引还是外部搜索服务。使用外部服务的,还要用 curl http://127.0.0.1:9200/_cat/indices?v(Elasticsearch)确认索引是否存在、文档数为不为 0。
第二步,比对行数。内容表有数据但索引表为空,就是没有重建:
SELECT COUNT(*) FROM posts; -- 正常有几十万
SELECT COUNT(*) FROM search_index; -- 返回 0 即为索引丢失
第三步,检查两件常被忽略的事:迁移后站点域名变了,索引里存的是旧域名链接,命中后又被过滤掉;以及缓存(Redis、页面缓存)里保存的还是旧的空搜索结果。
各类 CMS 具体怎么重建索引?
结论:能找到后台「重建索引 / 更新缓存」按钮的优先用按钮,找不到就用命令行工具,不要在数据库里手工插入索引记录。
WordPress 原生搜索走 wp_posts 的 SQL LIKE,本来不需要索引;装了插件才需要重建:Relevanssi 在「Relevanssi → Index → Build Index」重建,或用 WP-CLI 执行 wp relevanssi index;ElasticPress 执行 wp elasticpress index --setup --force;SearchWP 在「工具 → 重建索引」里执行。迁移后先跑一次 wp search-replace 'https://old.com' 'https://new.com' --all-tables --precise,把索引里的旧域名换掉。
Discuz、DedeCMS、PHPCMS 这类国产 CMS,一般在后台「全局 → 性能优化 / 更新缓存」里有重建帖子索引、重建统计的入口;使用 Sphinx 的,需在服务器执行 indexer --all --rotate(Manticore 同命令)。Sphinx 是独立的全文检索服务,重建期间旧索引仍可查询,--rotate 就是不停机切换。
使用 MySQL 全文索引的站点,执行 OPTIMIZE TABLE posts 可重建 InnoDB 全文索引;中文分词必须加 ngram 解析器,否则搜索「服务器」这类词基本无结果:ALTER TABLE posts ADD FULLTEXT INDEX ft_title(title) WITH PARSER ngram。
Elasticsearch 怎么做到不停机重建索引?
结论:不要在原索引上直接 reindex,新建一个带版本号的索引,灌完数据再用别名切换,全程不停服。
流程是四步:新建 posts_v2(mapping 与旧索引保持一致);用 POST _reindex?wait_for_completion=false&slices=auto 把 posts_v1 的数据搬到 posts_v2,slices: auto 会按分片数并行,千万级文档通常能提速数倍;用 _count 核对两边文档数;最后做别名切换:
POST /_aliases
{"actions":[
{"remove":{"index":"posts_v1","alias":"search"}},
{"add":{"index":"posts_v2","alias":"search"}}
]}
别名是给应用层使用的固定名称,切换后程序无需改配置。确认新索引正常后再删除 posts_v1。注意批量灌数据时单批 5000 条左右、并发不超过 2,否则容易触发 es_rejected_execution。
重建完成后怎么验证索引真的可用?
结论:重建成功不等于搜索可用,必须用真实关键词、游客身份和无结果页三方面验证一遍。
具体做法:抽 10 个迁移前有结果的高频关键词,逐一比对结果数量级;用未登录状态再搜一次,确认游客查询同样正常;搜 1 个字符应返回「关键词过短」提示,本站搜索关键词最小长度为 2 字符,这个限制在迁移后经常被误删;确认搜索限流配置没有被顺手清零(限流值填 0 表示不限次数,登录账号按账号计数、游客按 IP 计数),否则搜索接口容易被批量抓取;最后看前台搜索热词 TOP10 是否有数据。
下次迁移怎么避免再踩坑?
结论:把索引服务单列成迁移清单里的一行,并约定迁移后必须执行一次重建。
具体做法是:导出数据库时明确索引表是否需要一起导出(多数搜索索引可重建,不必导出以省体积);在迁移清单里写上「重建搜索索引」和「替换旧域名」两条;迁移完成后立刻跑一次抽样搜索,别等用户反馈才发现。GJ 站长论坛这类社区站点若在后台调整过搜索限流、最小关键词长度等参数,迁移后也要对照原配置逐项复核。