用Drupal好些年了,英文站的搜索感觉还行,但中文站的搜索明显不太好用,无论是性能、准确性等方面都体验不佳。也曾经用过Apache Solr来弥补,不过配置起来有点麻烦,而且最后的搜索结果也并不一定很理想。
大数据量的站点要想生成搜索索引就比较困难,在字段也多的情况下更是索引起来很慢,而且容易造成MySQL超时报错或者连接数堵塞。也想过减少一些不太必要索引的字段来降低索引负载,但大数据量的站点重新生成测试就需要等待很多天。这两天干脆拿一个数据量少的不重要站点来做测试,在“内容类型”的“管理显示”设置中添加“自定义显示设置”-“搜索索引”,然后把不需要索引的字段设置为“隐藏”,如果只有标题需要索引,可以把所有字段都设置为“隐藏”,而标题是默认会被索引的,这个我在直接打开MySQL中相关搜索表查看可以确认。通过减少索引的字段,重新索引后数据库中相应表的大小有所减少,证明这是一个有效降低负荷的办法。
另外关于中文,在搜索设置中一般会开启“简单CJK(中日韩字符)处理”(是否启用基于重叠排列的简单CJK(中日韩)语言php文件分析器。如果您想使用一个外部的预处理器,则请将该选项关闭。该设置不影响其他语言。),再把“索引关键词最小字数”进行修改,默认的3主要适合于英文站,而中文站很多人用2个甚至1个中文字来进行搜索,根据提示我怕设置过小会影响服务器性能,对于数据量稍大的站(例如数万以上)我一般是设置为2,只在个人博客等数据量很小的站设置为1。但在设置为2的站点上使用最小2个字来进行索引会导致无法搜索到只有1个特征值的内容(看后面补充的例子),我这两天测试改为1然后重新索引,发现最后表的大小竟然降低,搜索体验也更好,那以前的中文站点都可以准备改过来。批量设置的命令是:
drush vset minimum_word_size '1' drush vset search_cron_limit '100' drush search-reindex -y drush search-index
补充一个详细例子:
在设置为2的情况下,搜索“武汉市和平里”无结果,改为搜索“武汉市 和平里”有结果,在数据库中查找原因。
这是因为Drupal在对“武汉市江汉区和平里”这个字段进行搜索索引的时候,以2个字来进行索引就有这些组合:“武汉”、“汉市”、“市江”、“江汉”、“汉区”、“区和”、“和平”、“平里”8个2个字的组合,而用“武汉市和平里”来搜索的时候,把“武汉市和平里”划分为“武汉”、“汉市”、“市和”、“和平”、“平里”5个2个字的组合,其中的“市和”就在“武汉”、“汉市”、“市江”、“江汉”、“汉区”、“区和”、“和平”、“平里”里面找不到,所以搜索不到结果。
而人工加入一个空格进行分词后搜索“武汉市 和平里”,搜索词就划分为“武汉”、“汉市”、“和平”、“平里”4个2个字的组合,在“武汉”、“汉市”、“市江”、“江汉”、“汉区”、“区和”、“和平”、“平里”里面可以全部找到,所以搜索就有结果。
但问题是一般中国人都不会去对中文搜索词中间加入空格来进行人工分词,Drupal自带的简单CJK也不像是Google、百度等搜索引擎那样进行智能中文分词,这样就出现本来应该搜索得到,实际却让用户失望的情况。
解决的办法我想到的有三个:
- 嵌入Google、百度的站内搜索API,根本就不用Drupal自带的搜索,但缺点是可能收录不完整并且有搜索引擎的标记;
- 采用Apache Solr等专门的搜索插件取代Drupal自带的搜索,缺点是设置麻烦、维护麻烦,服务器负载也有一定影响;
- 把Drupal自带搜索的最小索引字符数改为1,缺点是可能搜索出来不太相关的内容,服务器负载依然比较大。
相比较来说,一些中小型网站采用第三个办法比较简单,也基本上可以解决多数问题。
评论