使用背景

    在mysql中优化的时候,对varchar,char,text对这些数据进行查询时,如果我们使用like ‘%单词’,是无法使用到索引,如果网站的数据量比较大,会拖垮网站的速度。比如在根据电影的剧情来查找电影的名称,比如根据歌词查找歌名。

    利用第三方搜索软件: Sphinx是一个独立的全文索引引擎,意图为其他应用提供高速低空间占用、搜索结果高相关度全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成。内置MySQL和PostgreSQL数据库数据源的支持。搜索API支持PHP、Python、Perl、Rudy和Java。


Coreseek介绍

    Coreseek 是一款中文全文检索/搜索软件,基于Sphinx研发并独立发布,专攻中文搜索和信息处理领域,适用于行业/垂直搜索、论坛/站内搜索、数据库搜索、文档/文献检索、信息检索、数据挖掘等应用场景



Windows安装部署

    1、下载解压,拷贝到我们指定一个目录下面

        

HanLP分词后怎么搜索问题_php

    2、在etc目录下面,把mysql的模板配置文件拷贝到上级目录,并修改为sphinx.conf

        

HanLP分词后怎么搜索问题_操作系统_02

    

HanLP分词后怎么搜索问题_操作系统_03

    3、配置数据源(对哪些数据进行建立索引)

        建立索引源:在一个配置文件中,可以建立多个索引源的。语法:source 索引源的名称。

 

source 名称{
            //具体的配置
        }
  
#源定义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
}
  
    4、配置索引,一个数据源,要对应一个索引。语法: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
}
  
    5、配置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/...
}


    6、根据配置文件里面的配置,生成索引文件

        要以管理员的方式进入到cmd,进入 到sphinx下面的bin目录

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

            --all:为配置文件中所有的索引创建索引文件。也可以使用索引的名字只为某一个索引创建索引文件

        

HanLP分词后怎么搜索问题_php_04

生成的索引文件

HanLP分词后怎么搜索问题_HanLP分词后怎么搜索问题_05

    7、要安装启动sphinx服务

语法:searchd.exe –c 配置文件 --install
        该命令对应的参数:searchd开启服务端    searchd -c 配置文件 索引名称
        服务器端默认监听 9312 端口。常用命令:
            -c : 指定配置文件路径    --stop : 停止当前服务    --status : 查看当前状态    --install : 安装为 windows 服务
            --delete: 删除windows服务    --port  port: 监听的端口    --index  indexName : 只查询某个索引,默认查询所有索引

        

HanLP分词后怎么搜索问题_php_06

HanLP分词后怎么搜索问题_HanLP分词后怎么搜索问题_07


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存储到该表中

        

HanLP分词后怎么搜索问题_操作系统_08


    3.添加增量数据源

       

HanLP分词后怎么搜索问题_数据库_09


    4.主索引不变,添加增量索引

       

HanLP分词后怎么搜索问题_HanLP分词后怎么搜索问题_10

    5.重新建立主索引,要把最大的id值保存的a表里面

        

HanLP分词后怎么搜索问题_sql_11

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

        

HanLP分词后怎么搜索问题_php_12


    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/>";
    }
?>