OSQA開發日誌

1、OSQA搭建
html

直接按照wiki:http://wiki.osqa.net/display/docs/Home
前端

根據本身的系統來選擇安裝。我用的ubuntu+python2.6+django1.3 (1.4能用,可是須要改不少地方)。安裝過程能夠參考wiki,解釋得已經很詳細。過程當中出現nomodule之類的都easy_install就能夠了。
node

Osqa下載以後要配幾個地方
 settings_local.py.dist重命名成settings_local.py。settings_local.py須要修改的地方:
python

        DATABASES={
        'default':{
        'ENGINE':'django.db.backends.mysql',
        'NAME':'osqa',
        'USER':'root',
        'PASSWORD':'root',
        'HOST':'127.0.0.1',
        'PORT':'3306',
        }

 根據本身的設置填寫
mysql

    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作全文搜索的話,追加
linux

        SPHINX_API_VERSION=0x116#refertodjangosphinxdocumentation
        SPHINX_SEARCH_INDICES=('search_question_index',)#atupleofindexnamesrememberabouta#commaafterthe
        SPHINX_SERVER='localhost'
        SPHINX_PORT=9312

而且在settings.py
web

        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。sql

到此,基本配置都已完成,無論用apache仍是簡單的manage.pyrunserver的方式均可以啓動,看到界面了。配置郵件能夠參考:(注:原文未說明)數據庫

接下來,注意到添加感興趣標籤的時候,輸入標籤名點擊添加就能夠看到剛纔的標籤已經在上面了,但是刷新以後發現不見了。因而查看代碼以後發現這句:
apache

    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
    官網也是這個樣子……….這樣的方式不太友好,在沒有該標籤的時候應該給用戶一個友好提示…


2、Coreseek實現OSQA的搜索
1. 兩個問題

一、Mysql全文索引不堪重用
二、搜索問題顯示沒有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)。

相關文章
相關標籤/搜索