使用mysql数据库作为数据源时,xunsearch出错,总结。
我的项目名称为sssde,配置文件sssde.ini如下:
project.name = sssde
project.default_charset = utf-8
server.index = 8383
server.search = 8384
[ssid]
type = id
[subject]
type = title
建立索引的语句(我是使用util/Indexer.php建立索引的):util/Indexer.php 项目名 --source=mysql://mysql用户名:访问密码@ip地址:端口号/databaseName --sql='select 字段名 from 表名' --clean --rebuild
例如我的项目名为"sssde",数据库为本地数据库,mysql用户名和密码为"root",“root”,databasename为GPuser,那么我的语句就是:
util/Indexer.php sssde --source=mysql://root:root@localhost/GPuser/ --sql='select uid,unickname from user_base' --clean
注意:
--clean是指先清空原来的索引再建立索引
--rebuild是指重建索引
使用上面的建立索引命令,需要先进入的“根目录/sdk/php”文件夹下。
错误一 Missing value of primary key (FIELD:ssid)
这句是指建立索引时,缺少主键。提示如图:
原因:配置文件中的字段[ssid],匹配不到数据源中的数据,至于为什么没有匹配到,请阅读源代码。这种情况多出现在数据源为数据库的情况下。
解决方法:修改配置文件,将字段[ssid]改成与数据表中的字段名,也就是和数据库保持一致。如果数据源非数据库,那么请尝试修改字段名为别的,尽量简单多试几次。
修改后的配置文件如下:
project.name = sssde
project.default_charset = utf-8
server.index = 8383
server.search = 8384
[uid]
type = id
[subject]
type = title
错误二 建立索引成功,查到的结果为0
建立索引成功,但是,搜索时候却总是没有任何结果(你要保证在正常的情况下,能够搜到结果)。如下图:
我遇到的情况的原因是:在建立索引时,主键(也就是,ini文件中,type=id的那个字段)建立索引成功,但是要用于搜索的那个字段([subject])没有建立索引,所以,当然没有搜索结果。
解决方案:修改配置文件sssde.ini,将字段[subject]改名为[unickname],这样字段名就和数据库里字段名一样了。然后再查询,成功了!!!!!!
原因:不清楚,但是至此,我已经完全不想再信官网上那句“字段名不必和数据库中的字段一致”这句话。
修改后的sssde.ini文件为:
project.name = sssde
project.default_charset = utf-8
server.index = 8383
server.search = 8384
[uid]
type = id
[unickname]
type = title
使用一 关于是数据库建立索引时,读取数据的条数
参读了util/Indexer.php和util/XSDataSource.class.php的源码后,发现使用Indexer.php工具建立索引,每次从数据库中读取到1000条记录。控制这个数据的参数是“PLIMIT”,它在util/XSDataSource.class.php的129行附近。源码如下:
/**
* SQL 数据库源
*
* @author hightman <hightman@twomice.net>
* @version 1.0.0
* @package XS.util
*/
class XSDatabaseDataSource extends XSDataSource
{
<span style="color:#ff0000;">const PLIMIT = 10000;</span>
private $sql, $offset, $limit;
private $db; /* @var $db XSDatabase */
/**
* 返回数据库输出字符集
* @return mixed 如果数据库不支持 UTF-8 转换则返回 false
*/
只要修改这个变量即可改变读取数据库速度。相信大家很清楚了吧!
使用二 关于编写自己的搜索接口
在阅读了util/Quest.php的代码后,对程序有了一定的了解。现在简单谈谈如何编写一个搜索接口的问题。
首先,必须引入文件“lib/XS.php”。使用require_once来导入即可。与require相比,require_once不会重复引入同一个文件。
接着,我们需要得到一个XS对象,这个对象像是一个存放数据和对象仓库,包罗了所有我们在项目中需要用到的对象,比如索引对象index,搜索对象search等等。新建XS对象后,获得search对象,然后通过对search进行参数设置就可以完成我们的搜索了。
上面的话,应该还是不清楚,没关系,接下来,我们一起阅读代码:
<?php
//不建议在测试和开发时,使用这句话。因为它会隐藏好多错误,信息,使得改错工作变得麻烦。
//error_reporting( E_ALL&~E_NOTICE );
//xunsearch的安装目录
$prefix = "/usr/local/xunsearch";
//加载XS.php,这步是必须的
require_once("$prefix/sdk/php/lib/XS.php");
//获得XS对象。这个参数是项目名,XS会根据项目名自动到app目录下寻找对应的.ini文件,并加载。
$xs = new XS("sssde");
if (empty($xs)){
//如果上面的方法失效,那就使用绝对路径的方法试一试了。
$xs = new XS("$prefix/sdk/php/app/sssde.ini");
}
//设置编码集,放置乱码
$xs->defaultCharset = "UTF-8";
//获得搜索对象
$search = $xs->getSearch();
/**
$query 要查询的词句 string
$fuzzy 是否模糊查询 bool
$synon 是否同义词查询 bool
$limit_num 查询结果的数目 int
$limit_offset 相对第一条记录的偏移量 int
这是我封装的函数,这个函数应该仅仅支持单词查询
*/
function search($query, $limit_num=20, $limit_begin=0, $fuzzy=true, $synon=true){
//没有这句,将无法使用上面的search变量
Global $search;
//设置是否开启模糊查询
$search->setFuzzy($fuzzy);
//设置是否开启同义词查询
$search->setAutoSynonyms($synon);
//使用$query,可以搜索到好多结果,组成结果集。设置这一项,我们从结果集中取到部分结果返回,满足分页的需要。$limit_offset指定的相对0号结果偏移位置。$limit_num,控制读取的条数。
$search->setLimit($limit_num, $limit_begin);
//设置查询的请求句子,之所以这么说,是因为$query可以是"窝么 AND 你们 NOT 吃饭"这样的句子。如果输入"我们 您",那么它将默认是AND连接
$search->setQuery($query);
//搜索,并用变量$docs存储取到的结果数组。这里每个doc为一个XSDocument对象
$docs = $search->search();
//获得本次查询的结果总数(这是个估值)
$matched = $search->getLastCount();
//获得搜索数据库中数据的总量
$total = $search->getDbTotal();
//将结果存储在这个对象中,并将其返回
$results = new Results();
$results->set_total_num($matched);
//本次返回
if(count($docs) == 0){
echo "------------------------$query---get 0 results---------------------------\n";
return null;
}else{
$res = "------------------------$query---get ".strval($matched)." results---------------------------\n";
//将结果一一取出
foreach($docs as $doc){
//标题高亮
$subject = $search->highlight($doc->subject);
//echo "$subject--\n";
if(!empty($doc)){
$data = $doc->getFields();
$result = new Result($data['uid'], $data['unickname']);
$results->add_result($result);
$res .= $data['unickname']." \t#".$data['uid']."\n";
}
}
echo $res;
return $results;
}
}
class Results{
private $total_num = 0;
private $result_array = array();
public function add_result($result){
array_push($this->result_array, $result);
}
public function set_total_num($value){
$this->total_num = $value;
}
public function get_total_num(){
return $this->total_num;
}
public function get_result_array(){
return $this->result_array;
}
}
class Result{
public $uid = -1;
public $unickname = '';
public function __construct($uid,$unick){
$this->uid = $uid;
$this->unickname = $unick;
}
}
//测试
search("部落");
search("字");
search("笑");
search("尼玛");
search("刘");