mysql全文索引中文分词在java中的实现_dicuz安装sphinx中文索引

Sphinx简介

Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如PHP,Python,Perl,Ruby等,同时为MySQL也设计了一个存储引擎插件。

Sphinx是独立的搜索服务端,不依赖MySQL,当Sphinx和MySQL结合部署时,Sphinx的数据来源为MySQL。服务器安装Sphinx,由sphinx.conf配置文件指定Sphinx的数据源,如何读取MySQL的数据内容,设置Sphinx对MySQL数据库的哪个表哪些字段建立索引,索引的返回数据必须是数值型。

Sphinx单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。Sphinx创建索引的速度为:创建100万条记录的索引只需 3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。

正确使用Sphinx搜索数据的操作方式主要有三种:

1、命令行的search工具:/usr/local/webserver/sphinx/bin/search –i threads test

2、php的api接口查询:原理是直接用fsockopen连接端口,传递数据取得返回结果。 Sphinx官方已经提供php的api接口,可以include api查询(本方案以该查询方法为主),也可以将其源代码编译成php扩展而无需include。

3、在mysql中将Sphinx安装为SphinxSE存储引擎,通过SphinxSE方式调用Sphinx。

因Sphinx搜索结果只返回INT类型数据,部署Sphinx搜索的核心是由搜索入口(search.php)提交的关键词到Sphinx中搜索,Sphinx返回对应的tid、pid等信息,再依据tid、pid到cdb_threads或者cdb_posts中搜索,得到结果集展示在页面上。

Sphinx的搜索速度非常快,而tid/pid都是主键查询,总体来说虽然用了多次查询,但是速度仍然非常快。

Sphinx全文检索方案架构图

f113f31e7721ccfc9b93e45f55ab1736.png

Sphinx工作流程图

a5c88e24466134be14ad7f4ec4e9fb9a.png

1. Database数据源,是Sphinx做索引的数据来源。因为Sphinx是无关存储引擎、数据库的,所以数据源可以是MySQL、PostgreSQL、XML等数据。2. Indexer索引程序,从数据源中获取数据,并将数据生成全文索引。可以根据需求,定期运行Indexer达到定时更新索引的需求。3. SearchdSearchd直接与客户端程序进行对话,并使用Indexer程序构建好的索引来快速地处理搜索查询。4. APP客户端程序。接收来自用户输入的搜索字符串,发送查询给Searchd程序并显示返回结果。

Sphinx工作原理

Sphinx的整个工作流程就是Indexer程序到数据库里面提取数据,对数据进行分词,然后根据生成的分词生成单个或多个索引,并将它们传递给searchd程序。然后客户端可以通过API调用进行搜索。

Sphinx中文分词

中文的全文检索和英文等latin系列不一样,后者是根据空格等特殊字符来断词,而中文是根据语义来分词,起搜索中应以词为依据,独立存在的单个汉字搜索几乎没有意义。目前大多数数据库尚未支持中文全文检索,如Mysql。故,国内出现了一些Mysql的中文全文检索的插件,做的比较好的有hightman的中文分词。Sphinx如果需要对中文进行全文检索,也得需要一些插件来补充。其中我知道的插件有 coreseek 和 sfc 。

1. CoreseekCoreseek是现在用的最多的sphinx中文全文检索,它提供了为Sphinx设计的中文分词包LibMMSeg 。并提供了多个系统的二进制发行版,其中有rpm,deb及windows下的二进制包。另外,coreseek也为sphinx贡献了以下事项:

  • GBK编码的数据源支持
  • 采用Chih-Hao Tsai MMSEG算法的中文分词器

2. sfcsfc(sphinx-for-chinese)是由网友happy兄提供的另外一个中文分词插件。其中文词典采用的是xdict。据其介绍,经过测试,目前版本在索引速度上(Linux 测试平台)基本上能够达到索引UTF-8英文的一半,即官方宣称速度的一半。(时间主要是消耗在分词上)。 现提供了与sphinx最新版(sphinx 0.9.10)同步的sphinx-for-chinese-0.9.10-dev-r2006.tar.gz 。此版本增加了sql_attr_string,经过本人的测试。其安装和配置都非常方便。happy兄在分词方面还有另外一个贡献——php-mmseg,这是php对中文分词的一个扩展库。

Sphinx安装步骤

1. 下载源码

1.下载地址

 https://github.com/zwxhenu/coreseek

2. 下载命令

git clone https://github.com/zwxhenu/coreseek

2. 安装mmseg3中文分词

1. 安装依赖

yum -y install gcc gcc-c++ autoconf python python-devel libiconv libtool

2. 编译安装mmseg-3.2.14

 cd mmseg-3.2.14
 ./configure --prefix=/usr/local/mmseg3
 make
 make install

3. 遇到的问题1). 遇到error:cannot find input file: src/http://Makefile.in

yum -y install libtool
aclocal
libtoolize --force
automake --add-missing
autoconf
autoheader
make clean
./configure --prefix=/usr/local/mmseg3
make
make install

2). 没有规则可以创建“all-am”需要的目标“data/uni.lib

 删除Makefile.am中的data/uni.lib
 automake
./configure --prefix=/usr/local/mmseg3
 make
 make install

3). 生产uni.lib

cd /usr/local/mmseg3/etc/
 /usr/local/mmseg3/bin/mmseg -u unigram.txt
cp unigram.txt.uni uni.lib

3. 安装coreseek

1.安装依赖软件

yum -y install expat expat-devel

2. 检查环境

sh buildconf.sh

3. 检查环境出问题1) 在 csft-4.1/buildconf.sh 文件&& aclocal 后加入:

 && automake --add-missing   

2) 把csft-4.1/configure.ac 文件中的AM_INIT_AUTOMAKE([-Wall -Werror foreign])改为:

AM_INIT_AUTOMAKE([-Wall foreign])

3) 在csft-4.1/configure.ac 文件中的AC_PROG_RANLIB后面加上:

m4_ifdef([AM_PROG_AR], [AM_PROG_AR])

4) 在 csft-4.1/src/sphinxexpr.cpp 文件中, 替换所有:

T val = ExprEval ( this->m_pArg, tMatch ); 为T val = this->ExprEval ( this->m_pArg, tMatch ); 

4. 配置编译选项 ./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

5. 配置编译选项问题解决1). 遇到MySQL include files... configure: error: missing include files.解决办法:

yum install mysql-community-embedded-devel.x86_64  mysql-community-devel.x86_64 mysql++-devel.x86_64

2). 提示libiconv无法找到,需要修改vi src/Makefile 文件,找 LIBS = 开头的行:

将LIBS = -lm -lz -lexpat  -L/usr/local/lib –lpthread修改成:
LIBS = -lm -lz -lexpat -liconv -L/usr/local/lib -lpthread

5. 编译&安装

make; 
make install

4. 命令行测试mmseg分词,coresekk搜索

1. 进入测试目录

cd testpack

2. 检查终端是否能显示中文

cat var/test/test.xml #此时应该正确显示中文

3. 进行分词和创建索引

 /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc var/test/test.xml
 /usr/local/coreseek/bin/indexer -c etc/csft.conf --all 

4. 检查搜索结果 1) 命令:

/usr/local/coreseek/bin/search -c etc/csft.conf 网络搜索 

2) 结果:

Coreseek Fulltext 3.2 [ Sphinx 0.9.9-release (r2117)] 
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
 using config file 'etc/csft.conf'...

index 'xml': query '网络搜索 ': returned 1 matches of 1 total in 0.003 sec
displaying matches:
1. document=1, weight=1, published=Thu Apr  1 22:20:07 2010, author_id=1

words:
1. '网络': 1 documents, 1 hits
2. '搜索': 2 documents, 5 hits</code></pre>

5. 配置sphinx与mysql

1. threads源定义

source threads
{
    type                    = mysql
    sql_host                = localhost
    sql_user                = root
    sql_pass                = mysql57@fangstar
    sql_db                  = discuz
    sql_port                = 3306  # optional, default is 3306
    sql_sock                = /var/lib/mysql/mysql.sock
    sql_query_pre           = SET NAMES utf8
    #sql_query_pre          = SET SESSION query_cache_type=OFF
    sql_query_pre           = CREATE TABLE IF NOT EXISTS pre_common_sphinxcounter ( indexid INTEGER PRIMARY KEY NOT NULL,maxid INTEGER NOT NULL)
    sql_query_pre           = REPLACE INTO pre_common_sphinxcounter SELECT 1, MAX(tid)-10 FROM pre_forum_thread

    sql_query = SELECT t.tid AS id,t.tid,t.subject,t.digest,t.displayorder,t.authorid,t.lastpost,t.special 
            FROM pre_forum_thread AS t 
            WHERE t.tid>=$start AND t.tid<=$end
    sql_query_range  = SELECT (SELECT MIN(tid) FROM pre_forum_thread),maxid FROM pre_common_sphinxcounter WHERE indexid=1
    sql_range_step      = 4096
    sql_attr_uint            = tid
    sql_attr_uint            = digest
    sql_attr_uint            = displayorder
    sql_attr_uint            = authorid
    sql_attr_uint            = special
    sql_attr_timestamp      = lastpost
    sql_query_info            = SELECT * FROM pre_forum_thread WHERE tid=$id
}

2. threads index定义

index threads
{
    source          = threads
    path            = /usr/local/coreseek/var/data/threads
    docinfo         = extern
    mlock           = 0
    morphology      = none
    min_word_len    = 1
    charset_type    = zh_cn.utf-8
    charset_dictpath = /usr/local/mmseg3/etc/
    min_prefix_len   = 0
    min_infix_len    = 1
    ngram_len        = 0
    html_strip       = 0
}

3. threads_minute 源定义

source threads_minute: threads
{
    sql_query_pre            =
    sql_query_pre            = SET NAMES utf8
    sql_query_pre           = SET SESSION query_cache_type=OFF
    sql_query_range            = SELECT maxid+1,(SELECT MAX(tid) FROM pre_forum_thread) FROM pre_common_sphinxcounter WHERE indexid=1
}

4. threads_minute 索引定义

#threads_minute
index threads_minute : threads
{
    source            = threads_minute
    path            = /usr/local/coreseek/var/data/threads_minute #windows下最好用全路径
}

5. posts 源定义

#posts
source posts
{
    type                    = mysql
    sql_host                = localhost
    sql_user                = root
    sql_pass                = mysql57@fangstar
    sql_db                  =  discuz
    sql_port                = 3306
    sql_query_pre            = SET NAMES utf8
#     sql_query_pre           = SET SESSION query_cache_type=OFF
    sql_query_pre            = REPLACE INTO pre_common_sphinxcounter SELECT 2, MAX(pid)-2 FROM pre_forum_post
    sql_query                = SELECT p.pid AS id,p.tid,p.subject,p.message,t.digest,t.displayorder,t.authorid,t.lastpost,t.special 
                                FROM pre_forum_post AS p LEFT JOIN pre_forum_thread AS t USING(tid) 
                                WHERE p.pid>=$start AND p.pid<=$end
    sql_query_range            = SELECT (SELECT MIN(pid) FROM pre_forum_post),maxid FROM pre_common_sphinxcounter WHERE indexid=2
    sql_range_step          = 4096
    sql_attr_uint            = tid
    sql_attr_uint            = digest
    sql_attr_uint            = displayorder
    sql_attr_uint            = authorid
    sql_attr_uint            = special
    sql_attr_timestamp        =lastpost
    sql_query_info            = SELECT * FROM pre_forum_post WHERE pid=$id
}

6. posts index定义

#posts
index posts
{
      source            = posts
      path              = /usr/local/coreseek/var/data/posts #windows下最好用全路径
      docinfo          = extern
      mlock            = 0
      morphology       = none
      min_word_len = 1
      html_strip         = 0
      charset_dictpath = /usr/local/mmseg3/etc/    #BSD、Linux环境下设置,/符号结尾
      charset_type     = zh_cn.utf-8
      #charset_debug   =   0
      ngram_len          = 0
}

7. posts_minute 源定义

  #posts_minute
source posts_minute : posts
{
      sql_query_pre            =
      sql_query_pre            = SET NAMES utf8
  #     sql_query_pre           = SET SESSION query_cache_type=OFF
      sql_query_range            = SELECT maxid+1,(SELECT MAX(pid) FROM pre_forum_post) FROM pre_common_sphinxcounter WHERE indexid=2
}

8. posts_minute index定义

#posts_minute
index posts_minute : posts
{
      source            = posts_minute
      path              = /usr/local/coreseek/var/data/posts_minute #windows下最好用全路径
}

9. 全局indexer定义

indexer
{
    mem_limit           = 256M
}

10. searchd服务定义

searchd
{
    listen              = 9312
    listen              =   /tmp/sphinx.sock
    log                 = /var/log/spinhx/searchd.log
    query_log           = /var/log/spinhx/query.log
    read_timeout        = 5
    client_timeout      = 300
    max_children        = 30
    pid_file            = /var/run/searchd.pid
    max_matches         = 1000
    seamless_rotate     = 1
    preopen_indexes     = 0
    unlink_old          = 1
    mva_updates_pool    = 1M
    max_packet_size     = 8M
    max_filters         = 256
    max_filter_values   = 4096
}

6. 启动服务,创建索引

1. 创建索引

 /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf -all

2.启动后台服务searchd

/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf

3. 后台服务测试

/usr/local/coreseek/bin/search -c /usr/local/coreseek/etc/sphinx.conf aaa

4. 自动化命令

crontab -e
* */4 * * *  /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx.conf -all --rotate

5. 关闭后台服务searchd

/usr/local/coreseek/bin/searchd -c /usr/local/coreseek/etc/sphinx.conf --stop

discuz 后台配置

1. 按照下图进行搜索设置

dec140a3e90956931ccb0ade3c8e0682.png

2. 点击提交

参考文献

  1. discuz论坛配置开启Sphinx全文搜索
  2. coreseek sphinx mmseg mysql 全文检索 安装 配置
  3. Coreseek/Sphinx安装测试配置指南
  4. Discuzx3 使用sphinx实现全文搜索功能
  5. 千万级Discuz!数据全文检索方案(Sphinx)
  6. centos安装coreseek
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值