sphinx分詞搜索

使用背景

    在mysql中優化的時候,對varchar,char,text對這些數據進行查詢時,若是咱們使用like ‘%單詞’,是沒法使用到索引,若是網站的數據量比較大,會拖垮網站的速度。好比在根據電影的劇情來查找電影的名稱,好比根據歌詞查找歌名。php

    利用第三方搜索軟件: Sphinx是一個獨立的全文索引引擎,意圖爲其餘應用提供高速低空間佔用、搜索結果高相關度全文搜索功能。Sphinx能夠很是容易的與SQL數據庫和腳本語言集成。內置MySQL和PostgreSQL數據庫數據源的支持。搜索API支持PHP、Python、Perl、Rudy和Java。html

Coreseek介紹

    Coreseek 是一款中文全文檢索/搜索軟件,基於Sphinx研發並獨立發佈,專攻中文搜索和信息處理領域,適用於行業/垂直搜索、論壇/站內搜索、數據庫搜索、文檔/文獻檢索、信息檢索、數據挖掘等應用場景mysql

Windows安裝部署

    一、下載解壓,拷貝到咱們指定一個目錄下面c++

        

    二、在etc目錄下面,把mysql的模板配置文件拷貝到上級目錄,並修改成sphinx.confsql

            

    三、配置數據源(對哪些數據進行創建索引)數據庫

        創建索引源:在一個配置文件中,能夠創建多個索引源的。語法:source 索引源的名稱。bootstrap

        source 名稱{windows

            //具體的配置api

        }數組

#源定義
source mysql
{
    type                    = mysql

    sql_host                = localhost
    sql_user                = root
    sql_pass                = 
    sql_db                  = other
    sql_port                = 3306
    sql_query_pre            = SET NAMES utf8

    sql_query                = SELECT info_id as id, dev, goods_code, exclusive_price FROM import_fail
                                                              #sql_query第一列id需爲整數
                                                              #title、content做爲字符串/文本字段,被全文索引
    #sql_attr_uint            = group_id           #從SQL讀取到的值必須爲整數
    #sql_attr_timestamp        = date_added #從SQL讀取到的值必須爲整數,做爲時間屬性

    sql_query_info_pre      = SET NAMES utf8                                        #命令行查詢時,設置正確的字符集
    sql_query_info            = SELECT * FROM import_fail WHERE id=$id #命令行查詢時,從數據庫讀取原始數據信息
    #sql_query_post = update a set max_id = (select max(info_id) from import_fail)    #把當前最大的id記錄到表a
}

    四、配置索引,一個數據源,要對應一個索引。語法:index 索引名

        index a67{

            //配置項

        }

#index定義
index mysql
{
    source            = mysql             #對應的source名稱
    path            = C:/wamp/bin/sphinx/var/data/fail #請修改成實際使用的絕對路徑,例如:/usr/local/coreseek/var/...(此處fail爲文件名不是目錄)
    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 = C:/wamp/bin/sphinx/etc/ #Windows環境下設置,/符號結尾,最好給出絕對路徑,例如:C:/usr/local/coreseek/etc/...
    charset_type        = zh_cn.utf-8
}

    五、配置sphinx服務器

#searchd服務定義
searchd
{
    listen                  =   9312
    read_timeout        = 5
    max_children        = 30
    max_matches            = 1000
    seamless_rotate        = 1
    preopen_indexes        = 0
    unlink_old            = 1
    pid_file = C:/wamp/bin/sphinx/var/log/fail.pid  #請修改成實際使用的絕對路徑,例如:/usr/local/coreseek/var/...
    log = C:/wamp/bin/sphinx/var/log/fail.log        #請修改成實際使用的絕對路徑,例如:/usr/local/coreseek/var/...
    query_log = C:/wamp/bin/sphinx/var/log/query.log #請修改成實際使用的絕對路徑,例如:/usr/local/coreseek/var/...
}

    六、根據配置文件裏面的配置,生成索引文件

        要以管理員的方式進入到cmd,進入 到sphinx下面的bin目錄

        語法格式:執行sphinx下的一個程序indexer.exe –c配置文件 –all | 索引的名字

            --all:爲配置文件中全部的索引建立索引文件。也能夠使用索引的名字只爲某一個索引建立索引文件

        生成的索引文件

    七、要安裝啓動sphinx服務

        語法:searchd.exe –c 配置文件 --install

        該命令對應的參數:searchd開啓服務端    searchd -c 配置文件 索引名稱

        服務器端默認監聽 9312 端口。經常使用命令:

            -c : 指定配置文件路徑    --stop : 中止當前服務    --status : 查看當前狀態    --install : 安裝爲 windows 服務

            --delete: 刪除windows服務    --port  port: 監聽的端口    --index  indexName : 只查詢某個索引,默認查詢全部索引

        

LAMP安裝部署

    1.Lamp環境準備
    2.下載支持中文的Sphinx ---> coreseek
    3.安裝環境
        m4,gcc,gcc-c++,automake,libtool
    4.安裝中文分詞組件mmseg
        ##安裝mmseg
        $ cd mmseg-3.2.14
        $ ./bootstrap    #輸出的warning信息能夠忽略,若是出現error則須要解決
        $ ./configure --prefix=/usr/local/mmseg3
        $ make && make install

    5.安裝coreseek前準備
        依賴mysql及依賴庫
            mysql-server
            mysql-devel

    6.安裝coreseek
        $ cd csft-3.2.14 或者 cd csft-4.0.1 或者 cd csft-4.1
        $ sh buildconf.sh    #輸出的warning信息能夠忽略,若是出現error則須要解決
        $ ./configure --prefix=/usr/local/coreseek  --without-unixodbc --with-mmseg --with-mmseg-includes=/usr/local/mmseg3/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg3/lib/ --with-mysql 
        $ make && make ins tall

配置

#
# Minimal Sphinx configuration sample (clean, simple, functional)
#

source post
{
    type                    = mysql
    sql_host                = localhost
    sql_user                = root
    sql_pass                =
    sql_db                    = test
    sql_port                = 3306    # optional, default is 3306

    #設置字符集
    sql_query_pre = set names utf8
    #設置數據來源
    sql_query= select id,title,content from post

    #sql_attr_uint            = group_id                #從sql讀取到的值必須爲整數
    #sql_attr_timestamp        = date_added    #從sql讀取到的值必須爲整數,做爲時間屬性

    #提取具體數據
    sql_query_info_pre = set names utf8        #命令查詢時設置正確的字符集
    sql_query_info            = SELECT * FROM post WHERE id=$id    #命令查詢時從數據庫讀取原始數據信息
}


#配置索引
index ind_post
{
    source    = post    #必須和源名稱一致
    path = /usr/local/coreseek/var/data/post    #配置生成的索引文件的存儲路徑
    docinfo        = extern
    
    #去除html標籤
    html_strip = 1
    #完整的去除指定標籤
    html_remove_elements = style,script
    #去除標籤的時候,留下點東西
    html_index_attrs = img=title,alt; a=title,alt
    
    #設置索引字符集
    charset_type    = zh_cn.utf-8
    #設置詞典
    charset_dictpath = /usr/local/mmseg3/etc/
}


indexer
{
    mem_limit                = 32M
}


searchd
{
    port                    = 9312
    log                        = /usr/local/coreseek/var/log/searchd.log
    query_log                = /usr/local/coreseek/var/log/query.log
    read_timeout            = 5
    max_children            = 30
    pid_file                = /usr/local/coreseek/var/log/searchd.pid
    max_matches                = 1000
    seamless_rotate            = 1
    preopen_indexes            = 0
    unlink_old                = 1
}

使用

1.基本搜索
    開啓服務接口
    /usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/csft.conf
2.處理高亮

    $opts = array(
        "before_match" => "<span style="color:red">",
        "after_match" => "</span>"
    );

    foreach($list as $key=>$val){
        $list[$key] = $sp->buildExcerpts($val,"ind_post",$keyword,$opts);
    }

    注意:處理後會變爲索引數組

3.設置匹配模式
    $sp->setMatchMode(SPH_MATCH_ANY);

    (1)SPH_MATCH_ALL 徹底匹配全部的詞

        如「冬天  的   雪」,並不會匹配 「我愛冬天」,但能夠匹配 「我朋友,愛冬天,和」。由於「冬天的雪」 被分紅 「冬天」,「的」,「雪」三個詞,匹配條件是同時包含這三個詞,「我愛冬天」裏只包含一個「冬天」

    (2)SPH_MATCH_ANY 匹配任意一個詞

        如「冬天   的     雪」,並會匹配 「我愛冬天」。"冬天的雪「 -》 」冬天「 」的「 」雪「,由於「我愛冬天」裏有一個「冬天」相匹配

    (3)SPH_MATCH_PHRASE 必須匹配整個短語

        如「冬天的雪」,不會匹配 「我朋友,愛冬天,和」,雖然都包含一樣的須要嚴格匹配再也不健忘,只匹配「冬天的雪」

    (4)SPH_MATCH_BOOLEAN 與,或,非,分組 &,or,!,()

        如:hello | world,查詢「手機」,或「冬天」,:

        <?php

            $sc = new SphinxClient();

            $res = $sc->query("手機|冬天");

    (5)SPH_MATCH_EXTENDED 支持一些擴展的語法

        支持 @字段 查詢,如查詢title包含 abc , content 包含 bcd的:'@title abc @content bcd'

4.設置排序模式
    1.按照默認權重排序
        $sp->setSortMode(SPH_SORT_EXTENDED,"@weight desc");

    2.人工干預排序
        1.配置文件設置屬性字段
            sql_attr_uint  = weight 
        2.重建索引
        3.排序
            $sp->setSortMode(SPH_SORT_EXTENDED,"weight desc @weight desc");

====================================
#開啓去除標籤
    html_strip                              = 1

#去除標籤的時候留下的信息
    html_index_attrs                        = img=alt,title; a=title;

#完整去除的標籤
    html_remove_elements                    = style, script

====================================
增量索引
    1.給數據庫添加一張表,記錄完整索引位置
        create table a(max_id int);

    2.修改配置文件中的主索引配置項,目的建完索引後,把最大的id存儲到該表中
        
    3.添加增量數據源
       
    4.主索引不變,添加增量索引
       

    5.從新創建主索引,要把最大的id值保存的a表裏面

        

    6.把增量索引合併到主索引上面

        
    7.能夠結合操做系統的計劃任務作定時腳本
        天天晚上4:30作主索引,每5分鐘作增量索引
        30 4 * * * /usr/local/coreseek/bin/indexer ind_post --rotate
        */5 * * * * /usr/local/coreseek/bin/indexer ind_postnew --rotate
====================================
更新詞典詞條
    1.編輯/usr/local/mmseg3/etc/unigram.txt   詞典模板文件
    2. ../bin/mmseg -u unigram.txt  從新獲得詞典
    3.替換詞典  mv unigram.txt.uni uni.lib
    4.從新建立索引

具體代碼

<?php
    header("content-type:text/html;charset=utf-8");

    //包含類文件
    require "C:/wamp/bin/sphinx/api/sphinxapi.php";

   //ini_set("display_errors", "Off");
   //error_reporting(E_ALL^E_NOTICE^E_WARNING);
    //接收關鍵字
    $keyword = $_GET["keyword"];

    //實例化sphinx對象
    $sp = new SphinxClient();

    //鏈接服務器
    $sp->setServer("localhost",9312);

    //設置匹配模式
    $sp->setMatchMode(SPH_MATCH_ANY);

    //設置返回結果集偏移量和數目
    $sp->setLimits(0,1000);

    //執行搜索
    $result = $sp->query($keyword,"mysql");
   //var_dump($result);exit;
    if($result["total"] == 0) exit("查無數據");

    //整理全部id
    $ids = join(",",array_keys($result["matches"]));
   //var_dump($ids);exit;

    //鏈接數據庫查數據
    $conn = mysql_connect("localhost",'root','') or die("error connecting");
    mysql_query("set names utf8");
    mysql_select_db('other',$conn);
    $sql = "select info_id , dev, goods_code, exclusive_price from import_fail where info_id in ({$ids})";
    $res = mysql_query($sql,$conn);

    $data = array();
    while($row = mysql_fetch_assoc($res)){
        $data[] = $row;
    }
   //var_dump($data);exit;

    $opts = array(
        "before_match" => "<span style='color:red'>",
        "after_match"=> "</span>"
    );
    //處理結果
    foreach($data as $key=>$val){
        $val = $sp->buildExcerpts($val,"mysql",$keyword,$opts);
        echo $val[1]."<br/>".$val[2]."<hr/>";
    }
?>
相關文章
相關標籤/搜索