基于Sphinx的中文全文检索解决方案
有时候,我们查询的时候不需要把所有的字段都检索出来,只需要查询某个就可以了。例如,我们只需要检索标题中包含“中国”的内容,标题的数据表字段是title
在代码中,我们需要这样来干就可以了
前面的我就略过不写了
恩,就是这样,很简单。不过如果内容是数字的,貌似不行,不知道为什么,有待继续研究
在代码中,我们需要这样来干就可以了
前面的我就略过不写了
<?
$tcol = null;
$mode = SPH_MATCH_ALL;
$cl = new SphinxClient ( );
$cl->SetServer ( $host, $port );
$cl->SetConnectTimeout ( 1 );
$cl->SetWeights ( array (100, 1 ) );
$cl->SetLimits ( $off, $limit, ($limit > 10000) ? $limit : 10000 );
$cl->SetRankingMode ( $ranker );
$cl->SetArrayResult ( true );
if ($m == 'title') {
$mode = SPH_MATCH_EXTENDED;
$tcol = '@' . $m . ' ';
}
$cl->SetMatchMode ( $mode );
$res = $cl->Query ( $tcol . join ( " ", $keywords ), $index );
?>
恩,就是这样,很简单。不过如果内容是数字的,貌似不行,不知道为什么,有待继续研究
开始我也不知道具体如何操作,后来向乔大叔询问了一下,大概明白了怎么个做法
具体就是:建立数据表的时候就多一个字段,字段名为deleted
当php操作删除数据的时候,同时对索引进行更新,使用UpdateAttributes
然后当你查询的时候设置过滤SetFilter,将deleted为1的排除就可以了
具体就是:建立数据表的时候就多一个字段,字段名为deleted
当php操作删除数据的时候,同时对索引进行更新,使用UpdateAttributes
然后当你查询的时候设置过滤SetFilter,将deleted为1的排除就可以了
今天把coreseek和目前干的项目进行了整合了,前台用的是php,测试数据在mysql里面,共有11w条数据
如果采用普通的mysql查询,页面运行的时间是0.9s,索引以后搜索索引再根据索引得到的id查询数据库详细信息的页面执行时间是0.03s,速度快了30倍,我很满意,哈哈
以下是php搜索索引的核心部分代码
如果采用普通的mysql查询,页面运行的时间是0.9s,索引以后搜索索引再根据索引得到的id查询数据库详细信息的页面执行时间是0.03s,速度快了30倍,我很满意,哈哈
以下是php搜索索引的核心部分代码
<?php
require_once AN_ROOT."/inc/sphinxapi.php";
require_once AN_ROOT."/res/adodb/adodb.inc.php";
$keywords = $_REQUEST['keywords'];
$info = getInfoCoreSeek($keywords,$_GET['page']);
function getInfoCoreSeek($keywords,$page=1) {
$mode = SPH_MATCH_ANY;
$host = "localhost";
$port = 3312;
$index = "*";
$limit = 4;
$ranker = SPH_RANK_PROXIMITY_BM25;
if(!$page) $page=1;
$page = intval($page);
$off = ($page-1)*$limit;
$cl = new SphinxClient ();
$cl->SetServer ( $host, $port );
$cl->SetConnectTimeout ( 1 );
$cl->SetWeights ( array ( 100, 1 ) );
$cl->SetMatchMode ( $mode );
$cl->SetLimits ( $off, $limit, ( $limit>10000 ) ? $limit : 10000 );
$cl->SetRankingMode ( $ranker );
$cl->SetArrayResult ( true );
$res = $cl->Query ( join(" ", $keywords), $index );
if($res) {
$pageL = PageQuery($res['total'],$page,4,"act=search&keywords=".$_REQUEST['keywords']);
foreach($res['matches'] as $v) {
$arrID[] = $v['id'];
}
$rs = $GLOBALS['db']->GetAll("select id,title,content from info where id in(".join(',', $arrID).")");
$GLOBALS['tpl']->assign('pageL', $pageL);
//echo '<pre>';
//print_r($res);
//echo '</pre>';
return $rs;
}
}
?>
我在使用coreseek的时候,默认值,即csft.conf中的charset_type = sbcs。如果是这样的话,当我们进行搜索的时候
其返回值的中文将会是乱码,因为sbcs的定义是“Single Byte Character Set 单字节字符集“,这样是不符合我们的需求的,所以我们需要中文的utf-8。根据文档中的描述,charset_type 的另一个选项是utf-8,但实际上这对于中文是不行的。
下面,我将我的方法写出来供新手参考:
首先,复制mmseg中的data文件夹到你的mmseg的安装目录中,当然,可以不这么做,但是我希望是将有联系的东西放在一起便于查找
这里可以根据你的情况设定具体的路径
然后进入刚才的路径,生成字典文件。
运行以下命令生成字典
会生成一个unigram.txt.uni文件,将这个文件改名或者复制为uni.lib在当前文件夹
sudo /usr/local/coreseek/bin/search 测试
其返回值的中文将会是乱码,因为sbcs的定义是“Single Byte Character Set 单字节字符集“,这样是不符合我们的需求的,所以我们需要中文的utf-8。根据文档中的描述,charset_type 的另一个选项是utf-8,但实际上这对于中文是不行的。
下面,我将我的方法写出来供新手参考:
首先,复制mmseg中的data文件夹到你的mmseg的安装目录中,当然,可以不这么做,但是我希望是将有联系的东西放在一起便于查找
sudo cp /home/anerg/software/mmseg.3.0b3/data/ /usr/local/mmseg/ -R
这里可以根据你的情况设定具体的路径
然后进入刚才的路径,生成字典文件。
cd /usr/local/mmseg/data
运行以下命令生成字典
sudo /usr/local/mmseg/bin/mmseg -u unigram.txt
会生成一个unigram.txt.uni文件,将这个文件改名或者复制为uni.lib在当前文件夹
sudo cp unigram.txt.uni uni.lib
» 阅读全文
先去官方网站下载最新的2个包,我下的是3.0 beta4,得到以下两个包
csft3_0b4.tar.gz
mmseg3_0b3.tar.gz
我将其放在/home/anerg/software了
解压
编译mmseg
很不幸,这里我出错了,错误提示为:css/UnigramCorpusReader.cpp:89: error: 'strncmp' was not declared in this scope
手动修改了src/css/UnigramCorpusReader.cpp
在上面添加了一句
csft3_0b4.tar.gz
mmseg3_0b3.tar.gz
我将其放在/home/anerg/software了
解压
tar -xzvf mmseg3_0b3.tar.gz
tar -xzvf csft3_0b4.tar.gz
tar -xzvf csft3_0b4.tar.gz
编译mmseg
cd mmseg*
sudo ./configure --prefix=/usr/local/mmseg
sudo make
sudo ./configure --prefix=/usr/local/mmseg
sudo make
很不幸,这里我出错了,错误提示为:css/UnigramCorpusReader.cpp:89: error: 'strncmp' was not declared in this scope
手动修改了src/css/UnigramCorpusReader.cpp
在上面添加了一句
#include <string.h>
» 阅读全文






