一、OSQA搭建
直接按照wiki:http://wiki.osqa.net/display/docs/Home
根据自己的系统来选择安装。我用的ubuntu+python2.6+django1.3 (1.4能用,但是需要改很多地方)。安装过程可以参考wiki,解释得已经很详细。过程中出现nomodule之类的都easy_install就可以了。
Osqa下载之后要配几个地方
settings_local.py.dist重命名成settings_local.py。settings_local.py需要修改的地方:
DATABASES={ 'default':{ 'ENGINE':'django.db.backends.mysql', 'NAME':'osqa', 'USER':'root', 'PASSWORD':'root', 'HOST':'127.0.0.1', 'PORT':'3306', }
根据自己的设置填写
APP_URL='http://127.0.0.1:8000' LANGUAGE_CODE='cn'#汉化得已经很不错了 DJANGO_VERSION=1.3#填写自己的django版本 DISABLED_MODULES=['mysqlfulltext','books','recaptcha','project_badges']#trunk的默认用的是mysql全文索引,需要把这个加到diabledmodule!
如果用sphinx做全文搜索的话,追加
SPHINX_API_VERSION=0x116#refertodjangosphinxdocumentation SPHINX_SEARCH_INDICES=('search_question_index',)#atupleofindexnamesrememberabouta#commaafterthe SPHINX_SERVER='localhost' SPHINX_PORT=9312
并且在settings.py
INSTALLED_APPS=[ 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'django.contrib.humanize', 'django.contrib.sitemaps', 'django.contrib.markup', 'forum', 'djangosphinx', ]
当然,要用sphinx就easy_install django-sphinx和sphinxsearch。
到此,基本配置都已完成,不管用apache还是简单的manage.pyrunserver的方式都可以启动,看到界面了。配置邮件可以参考:(注:原文未说明)
接下来,注意到添加感兴趣标签的时候,输入标签名点击添加就可以看到刚才的标签已经在上面了,可是刷新之后发现不见了。于是查看代码之后发现这句:
froumviewscommands.py line 536 try: t = Tag.objects.get(name=tag) mt = MarkedTag(user=request.user, reason=reason, tag=t) mt.save() except : pass
就是说,如果该标签不存在在数据库,不是已有的标签,就会静静地pass,而前端还能显示能加到。
osqa1.png
官网也是这个样子……….这样的方式不太友好,在没有该标签的时候应该给用户一个友好提示…
二、Coreseek实现OSQA的搜索
1. 两个问题
1、Mysql全文索引不堪重用
2、搜索问题显示没有match的。即使输入的是某个标题的关键字也搜不到,最后几天便一直卡在这个问题上。
Google了N多,试了又试,无意间在settings.py所在的目录看到有个log文件夹。里面有个django.osqa.log文件Tail-fdjango.osqa.log,在页面发一个搜索请求,看到了它其实用的是mysql的全文索引。如果表里没有数据,则搜索不到问题。
后来终于在/home/osqa/osqaweb/log目录下的django.osqa.log文件中看到这句,这个表forum_mysqlftsindex就是用mysql做全文索引建的表,建个trigger在每次人问问题和回答问题,都会触发这个触发器,并且重新将该问题相关的全部内容都重新更新到索引表:
osqa2.png
接下来试试搜索问题 也能看到这样:
osqa3.png
所以,很明显,默认的用的是mysqlfulltext,搜索的时候也走的这条线。
在这之前,试图很多次开启sphinxfulltext模块的时候,settings等地方需要都改了,需要配的都配了,但是始终在sphinx的服务端没有看到任何请求过来,coreseek虽然是第一次使用,但是对sphinx已经用了很久,所以能肯定sphinx的server端肯定是没有问题的。在看到上面的log之后就确定是默认走的是mysql的全文索引,于是在disabledmodule里将mysqlfulltext加上。就试了试搜索,就看到如下的结果:
osqa4.png
应该走的是django的模糊匹配,我的keyword是 ask,它就到forum_node这个问题表中用like ‘%ask%’这样的模糊匹配去取数据。当然,直接去这里找当然能找到了,页面也能显示相应的问题了,但是like毕竟不是长久之计,本身也对MySQL数据库产生巨大的压力,也就是说,表forum_mysqlftsindex就是用mysql做全文索引建的表,那么现在咱们得废掉这个MySQL本身提供的全文索引,寻找一种更为有效的全文索引方式或解决方案。
2. 基于sphinx之上的Coreseek实现搜索
下面就考虑给osqa的搜索用sphinx实现。因为包含中文搜索,虽然sphinx可以通过设定编码和有效字符集支持中文,但是中文分词搞不定,就用coreseek来实现,coreseek整合了分词+搜索。
(1)第一步安装coreseek:http://www.coreseek.cn/
coreseek官网稳定版是3.2.14,是基于sphinx0.9.9的。
安装过程也没什么,直接参照:
http://www.coreseek.cn/products/products-install/install_on_bsd_linux/
先安装分词模块mmseg,出现如下所示的结果就可以了:
$ /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc src/t1.txt
中文/x 分/x 词/x 测试/x
中国人/x 上海市/x
Word Splite took: 1 ms
(2 )第二步是csft
看到如下所示表示已经安装成功:
$ /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx-min.conf.dist
##以下为正常测试时的提示信息:
Coreseek Fulltext 3.2 [ Sphinx 0.9.9-release (r2117)]
Copyright (c) 2007-2010,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
using config file '/usr/local/coreseek/etc/sphinx-min.conf.dist'...
total 0 reads, 0.000 sec, 0.0 kb/call avg, 0.0 msec/call avg
total 0 writes, 0.000 sec, 0.0 kb/call avg, 0.0 msec/call avg
(3) OSQA内Sphinx配置文件
接下来为我们的问题搜索写sphinx配置文件,我的配置文件如下:
#源定义 sourcebase_source { type=mysql sql_host=localhost sql_user=root sql_pass=root sql_db=osqa sql_port=3306 sql_query_pre=SETNAMESutf8 sql_query_pre=SETSESSIONquery_cache_type=OFF sql_query_info_pre=SETNAMESutf8 sql_range_step=1000 sql_query= } #index定义 indexbase_index { path= source=base_source#对应的source名称 docinfo=extern mlock=0 morphology=none min_word_len=1 html_strip=0 #中文分词配置,详情请查看:http://www.coreseek.cn/products-install/coreseek_mmseg/ charset_dictpath=/usr/local/mmseg3/etc/#BSD、Linux环境下设置,/符号结尾 #charset_dictpath=etc/#Windows环境下设置,/符号结尾,最好给出绝对路径,例如:C:/usr/local/coreseek/etc/... charset_type=zh_cn.utf-8 ngram_len=0 } sourcesearch_question_source:base_source { sql_query_range=selectmin(id),max(id)fromforum_node sql_query=SELECTquestion.id,question.title,author.username,question.tagnames,question.body, GROUP_CONCAT(answer.body)asanswer_bodiesFROMforum_nodeASquestion,forum_nodeASanswer, auth_userASauthorWHEREanswer.parent_id=question.idANDquestion.author_id=author.id Andquestion.id>=$startandquestion.idDATE_FORMAT(NOW(),'%Y-%m-%d') } indexsearch_question_index:base_index { source=search_question_source path=/ROOT/sphinx/index/search_question } indexdelta_search_question_index:search_question_index { source=delta_search_question_source path=/ROOT/sphinx/index/delta_search_question } #全局index定义 indexer { mem_limit=128M } #searchd服务定义 searchd { listen=9312 read_timeout=5 max_children=30 max_matches=1000 seamless_rotate=0 preopen_indexes=0 unlink_old=1 pid_file=/ROOT/sphinx/log/searchd_osqa.pid#请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/... log=/ROOT/sphinx/log/searchd_osqa.log#请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/... query_log=/ROOT/sphinx/log/query_osqa.log#请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
可以放在任何文件夹下只要建索引的时候指定就好。比如我的是放在/ROOT/sphinx/conf/sphinx_osqa.conf,接下来建索引:
indexer -c /ROOT/sphinx/conf/sphinx_osqa.conf --all –rotate
Base_index的警告可以忽略,然后启动守护进程:
searchd –c /ROOT/sphinx/conf/sphinx_osqa.conf
到此,sphinx的服务端都已经弄好,守护进程searchd在9312端口等待客户端发query。可以简单测试一下
search –c /ROOT/sphinx/conf/sphinx_osqa.confkeywords
3. Sphinx服务端配置的几个问题
Sphinx服务端配置已经完成,虽然自从diable掉mysqlfulltext之后就可以搜到问题,但是用的是Like%keyword%形式的请求。我们现在需要改的有三处:
(1)在/forum/models/question.py
在Question类加入
search=SphinxSearch( index='search_question_index', mode='SPH_MATCH_ALL', )
自己根据需求配置,比如设置权重之类的。
(2)加入sphinx search,引用
from djangosphinx.models import SphinxSearch
(3) QuestionManager类加入
queryset=Question.search.query(keywords)
将命中的id取出来存成list结构,比如,存到变量ids里,然后直接返回
return False,self.filter(id__in=ids)
这样就返回了命中的id的所有问题。当然这种in的方式如果ids的数据量小的时候还可以,大了之后也不行,所以,后续应该考虑分页的方式来呈现更多的结果。
当然,最终能在服务器端上看到已经有收到请求了,如下图所示:
osqa5.png
至此,之前搜到不到关键词/tag的问题成功解决。也就是说,咱们的StackOverflow的原型OSQA已经搭建完成,接下来,便是一系列修改完善优化的工作。
感谢技术知己之一罗勍:http://weibo.com/u/1909128871。(项目已终止,2012.07.17)。