sphinx中文分词搜索coreseek windows下安装与基本使用简介

2013-05-04 17:11:00 来源: 互联网

这是半年前没有对外写的文章,现在拿出来分享下。可能会有一些不正确或不严谨的地方,某些语言可能比较轻浮,请见谅。

 

首先说明一下coreseek其实就是基于sphinx的中文分词版本,sphinx本身并没有提供中文分词功能,需要自行安装中文词库比较麻烦,coreseek提供了中文分词功能,提供了完整的官方中文使用文档,并且在使用上和官方的sphinx并没有差别。以coreseek-4.1版本为例

下载地址 http://www.coreseek.cn/news/14/54/ 

帮助手册 http://www.coreseek.cn/products-install/ 

 

下面开始coreseek的安装

安装过程很简单,下载coreseek-4.1-win32.zip,解压至某一个文件夹,这里假设放在d:\coreseek下,双击打开test.cmd进行测试,会出来一串命令行的提示信息,留意提示信息,如果没有提示错误就算安装完成

 

安装后,先别急着怎么使用,首先要配置好文档,解缩包中有测试文件这里测试也略,教程尽量简单点(其实是我懒。。)

配置文件的位置可以放在任何地方,不过建议就放在d:\coreseek\bin\的目录好了,d:\coreseek\etc\目录下提供了好多配置的参考,我们把csft_mysql.conf复制至d:\coreseek\bin\下,命名为sphinx.conf(可任意名称),打开它看到的内容大概是这样:

#源定义

source mysql

{

    type                    = mysql

 

    sql_host                = localhost

    sql_user                = root

    sql_pass                = 

    sql_db                    = test

    sql_port                = 3306

    sql_query_pre            = SET NAMES utf8

 

    sql_query                = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content FROM documents

                                                              #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 documents WHERE id=$id #命令行查询时,从数据库读取原始数据信息

}

 

#index定义

index mysql

{

    source            = mysql             #对应的source名称

    path            = var/data/mysql #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

    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

}

 

#全局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 = var/log/searchd_mysql.pid  #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

    log = var/log/searchd_mysql.log        #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

    query_log = var/log/query_mysql.log #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

    binlog_path =                                #关闭binlog日志

}


 


这么多字段干嘛用的。。。

先别管这个,看文件中的配置格式

source mysql

{

    ...

}

 

index mysql

{

    ...

}

....


这些就是配置文件中的'类',配置格式就是以类为基础的,类的格式是 '关键字 [名称] {}',每个关键字的作用:

source:定义数据索引源(就是被搜索的数据啦),如果以mysql为索引源,那么source里的信息包含数据库账号、密码、端口、获取数据索引的sql语句等

index:定义如何处理索引源,例如索引文件目录、分词单位、分词配置文件、去除数据的html标签等

indexer:定义indexer服务设置,例如内存使用大小限制、文件索引大小限制

searchd:定义searchd服务设置,用于搜索时的设置,例如服务端口、搜索最大数量限制、搜索超时时间等

 

其实配置文件中好多字段都有默认值的,并不需要我们进行配置(不用写出来),下面对一些常用的配置字段进行解释,以mysql数据库为例

基本环境:

主机 localhost

账号 root

密码 root

端口 3306

数据库 ibos

数据表:email

数据结构

CREATE TABLE email (
emailid mediumint(8) unsigned NOT NULL auto_increment COMMENT '邮件id',

fromid int(10) unsigned NOT NULL default '0' COMMENT '发送人ID',

toid int(10) unsigned NOT NULL default '0' COMMENT '收件人ID',
content text unsigned NOT NULL COMMENT '邮件内容',
subject varchar(100) unsigned NOT NULL COMMENT  '邮件标题',

sendtime int(10) NOT NULL COMMENT '发送时间',

attachment varchar(100) NOT NULL COMMENT '附件ID,以逗号分割',
PRIMARY KEY (emailid),
) ENGINE=MyISAM';

 

配置内容:

#定义数据源,取一个好听的名字,就叫email吧。。。

source attach {

    type                        =     mysql    #定义数据源的类型

    sql_host                  =     localhost

    sql_user                  =     root

    sql_pass                  =     root

    sql_db                     =     ibos

    sql_port                   =     3306

 

    #sql_query_pre是获取数据源前执行的操作,内容是mysql可执行的语句,你可以设置多个sql_query_pre,sphinx将会按顺序执行

    sql_query_pre         =     SET NAMES utf8    #一般设置好编码以保证数据格式正确

    sql_query_pre         =     xxx

    

    #sql_query就是真正获取数据源的语句,内容是mysql可执行的语句

    #SELECT的第一个字段是非负整数并且值都不相同的,搜索结果返回的ID就是这个,建议使用数据表的主键,这里是emailid

    #其它字段是用来设置搜索条件和希望被搜索的字段,如果那个字段你认为对搜索没有作用,那就不要选择

    sql_query                = SELECT emailid,fromid,toid,subject,content,sendtime,attachement FROM email

 

    #sql_attr_    索引属性,主要被用来设置搜索条件,并且搜索结果返回的信息也包含这些属性的值

    #设置某个属性的前提是在sql_query中有返回这个字段的数据

    #sql_attr_uint,从SQL读取到的值必须为整数

    sql_attr_uint            = fromid

    sql_attr_uint            = toid

    #sql_attr_timestamp,从SQL读取到的值必须为整数,作为时间属性

    sql_attr_timestamp  = sendtime

    

    #程序运行前执行的查询操作,这个没有什么意义,可以不写,仅仅用于调试目的

    sql_query_info    =    SELECT * FROM email

}

 

#接下来要配置如何处理索引源,名称建议和索引源一样吧

index email {

    source                 = email    #对应的source名称

    path                    = d:\coreseek\data\email    #生成索引文件的路径(包含文件名),可自定义

    min_word_len     = 1    #最小分词长度

    html_strip            = 1    #是否去除html标签,强烈建议开启此项,像邮件这些富文本包含大量html标签,对搜索没有任何帮助,而且增加搜索时间和索引文件大小(至少增大5倍以上)

    charset_dictpath = d:\coreseek\etc\    #中文分词配置文件目录

    charset_type        = zh_cn.utf-8

}

 

#还可以定义多个索引源

source diary {

}

index diary {

    source :diary

}

 

#indexer服务定义,注意没有名字!这个设置是全局的!

indexer {

    mem_limit            = 128M    #内存大小限制

}

 

#searchd服务定义,注意没有名字!这个设置是全局的!

searchd {

    listen                         =  9312    #服务端口,默认9312

    read_timeout            = 5          #最大搜索时间
    max_matches            = 1000    #最大匹配数

    max_children            = 30        #子进程数目限制

    #这几项看文档吧

    pid_file                      = d:\coreseek\var\log\searchd_mysql.pid

    log                             = d:\coreseek\var\log\searchd_mysql.log        #全部searchd运行时事件会被记录在这个日志文件中。

    query_log                   = d:\coreseek\var\log\query_mysql.log          #全部搜索查询会被记录在此文件中

}

 

了,配置就到这里,那如何进行搜索,那就要用到cmd命令行,别吓着了,其实我们记住三个命令就可以了

开始 - 运行 - cmd    打开命令行模式

建立索引

d:\coreseek\bin\indexer -c d:\coreseek\bin\sphinx.conf --all   #sphinx.conf就是刚刚我们的配置文件

按回车,如无意外会看到正在建立索引的信息,稍等一会就可以了

 

开始搜索,注意命令行模式并不支持中文搜索(用其它方式,例如PHP没问题),coreseek官方有解决办法,但是我们一般不用命令行进行搜索,这里只是测试

d:\coreseek\bin\search -c d:\coreseek\bin\sphinx.conf 搜索字符串

例:搜索banana

d:\coreseek\bin\search -c d:\coreseek\bin\sphinx.conf banana

如无意外就会有搜索结果信息了。。。

 

打开控制台,这条和搜索那条命令不一样,是searchd不是search,这个命令下一篇讲PHP的时候会用到

d:\coreseek\bin\searchd -c d:\coreseek\bin\sphinx.conf    #Ctrl + c 可关闭控制台

打开控制台的作用就是让让sphinx监听端口,接收搜索命令,例如用PHP代码执行sphinx搜索就要打开控制台

 

 

 

更多知识

 

继承

因为是类,所以可以继承。。

定义父类email

source email {

    ....

}

定义子类subemail继承email类的所有设置:

source subemail : email { #除了source,index也可以使用继承

    ....

}

子类中可以重载email中的设置

source subemail : email {

    sql_host      = www.ibos.com.cn    #重载主机

    sql_query    = SELECT * FROM subemail    #重载sql_query语句

}


其实继承很少被使用到,但有一个很实用的例子就是有很多数据源使用同一数据库的时候,继承就派上用场了

source setdb {     #setdb类只实现连接数据库

    sql_host                  =     localhost

    sql_user                  =     root

    sql_pass                  =     root

    sql_db                     =     ibos

    sql_port                   =     3306

}

souce email : setdb{    #继承setdb类

    sql_query = ...        #直接写查询语句,而不用再写数据库信息

}

souce diary : setdb {

    sql_query = ...  

}

 

souce article : setdb {

    sql_query = ...  

}

souce forum : setdb {

    sql_query = ...  

}

 

增量索引

以下是出自官方文档,觉得官方解释得比较清楚,更多例子参考文章中的附件 IBOS的配置文件中email的增量索引配置


有这么一种常见的情况:整个数据集非常大,以至于难于经常性的重建索引,但是每次新增的记录却相当地少。一个典型的例子是:一个论坛有1000000个已经归档的帖子,但每天只有1000个新帖子。

在这种情况下可以用所谓的“主索引+增量索引”(main+delta)模式来实现“近实时”的索引更新。

这种方法的基本思路是设置两个数据源和两个索引,对很少更新或根本不更新的数据建立主索引,而对新增文档建立增量索引。在上述例子中,那1000000个已经归档的帖子放在主索引中,而每天新增的1000个帖子则放在增量索引中。增量索引更新的频率可以非常快,而文档可以在出现几分种内就可以被检索到。

确定具体某一文档的分属那个索引的分类工作可以自动完成。一个可选的方案是,建立一个计数表,记录将文档集分成两部分的那个文档ID,而每次重新构建主索引时,这个表都会被更新。

# in MySQL

CREATE TABLE sph_counter

(

    counter_id INTEGER PRIMARY KEY NOT NULL,

    max_doc_id INTEGER NOT NULL

);

 

# in sphinx.conf

source main

{

    # ...

    sql_query_pre = SET NAMES utf8

    sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents

    sql_query = SELECT id, title, body FROM documents \

        WHERE id<=( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )

}

 

source delta : main

{

    sql_query_pre = SET NAMES utf8

    sql_query = SELECT id, title, body FROM documents \

        WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )

}

 

index main

{

    source = main

    path = /path/to/main

    # ... all the other settings

}

 

# note how all other settings are copied from main,

# but source and path are overridden (they MUST be)

index delta : main

{

    source = delta

    path = /path/to/delta

}

请注意,上例中我们显示设置了数据源delta的sql_query_pre选项,覆盖了全局设置。必须显示地覆盖这个选项,否则对delta做索引的时候也会运行那条REPLACE查询,那样会导致delta源中选出的数据为空。可是简单地将delta的sql_query_pre设置成空也不行,因为在继承来的数据源上第一次运行这个指令的时候,继承来的所有值都会被清空,这样编码设置的部分也会丢失。因此需要再次显式调用编码设置查询。