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/>";
    }
?>
相关文章
相关标签/搜索