创作人 Leo
编辑时间 Wed Jan 1,2020 at 10:13
该软件是对 xapian + SCWS 的二次封装
动态配置文件
1.通过不同的配置文件实现不同的搜索需求
在实例化搜索对象时指定文件即可
这两个文件指向同一个project即可
例:
test.php
<?php
$xs = new XS ( 'citysFuzzy' );
$xs2 = new XS ( 'citys' );
...
?>
citysFuzzy.ini
project.name = citys
project.default_charset = utf-8
...
citys.ini
project.name = citys
project.default_charset = utf-8
...
2.使用 XSFieldScheme 类动态配置
例:
<?php
$xunsearch = new Xunsearch ();
$fs = new XSFieldScheme();
$fs->addField('pid',array('type'=>'id')) ;
$fs->addField('seller_pid',array('type'=>'string', 'index'=>'both')) ;
$fs->addField('title', array('type'=>'string', 'index'=>'both')) ;
$fs->addField('des_continent', array('type'=>'string', 'index'=>'both', 'tokenizer'=>'split(,)')) ;
$fs->addField('des_country', array('type'=>'string', 'index'=>'both', 'tokenizer'=>'split(,)')) ;
$fs->addField('des_city', array('type'=>'string', 'index'=>'both', 'tokenizer'=>'split(,)')) ;
$xs = $xunsearch->XS ( 'product' );
$xs->setScheme($fs);
$search = $xs->search;
?>
模糊匹配
分词查询默认使用 AND 关系查询,开启模糊匹配改为 OR 关系,可以使用 setFuzzy 开启模糊查询
开始模糊查询,解析后的语句:’Xapian::Query((C法国:(pos=1) OR C日本:(pos=2)))’
关闭模糊查询,解析后的语句:’Xapian::Query((C法国:(pos=1) AND C日本:(pos=2)))’
例:测试php程序
product.ini
project.name = product
project.default_charset = utf-8
server.index = 127.0.0.1:8383
server.search = 127.0.0.1:8384
[pid]
type = id
[seller_pid]
type = string
index = both
[title]
type = string
index = both
[des_continent]
type = string
index = both
tokenizer = split(,)
[des_country]
type = string
index = both
tokenizer = split(,)
[des_city]
type = string
index = both
tokenizer = split(,)
[dep_continent]
type = string
index = both
tokenizer = split(,)
[dep_country]
type = string
index = both
tokenizer = split(,)
[dep_city]
type = string
index = both
tokenizer = split(,)
[type_name]
type = string
index = both
[sub_type_name]
type = string
index = both
[seller]
type = string
index = none
product.php
<?php
include 'xunsearch/lib/XS.php';
define('FUZZY', true); //是否开启模糊匹配
define('BREAK_LINE', '<br /><br />');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset='utf-8'>
<title>Lalalalala</title>
<style>
em{
color: red;
}
</style>
</head>
<body>
<Pre>
<?php
$breakline = BREAK_LINE ;
$keywords = '法国日本'; //搜索关键词
echo 'keywords : ',var_export($keywords, true), $breakline;
try {
$xs = new XS ( 'product' );
$keywords = empty ( $keywords ) ? '' : 'title:'.$keywords;
$search = $xs->search;
if (FUZZY)
$count = $search->setFuzzy()->count ( $keywords );
else
$count = $search->count ( $keywords );
echo '总数:' , var_export($count, true), $breakline;
if (FUZZY)
$search->setFuzzy()->setQuery ( $keywords );
else
$search->setQuery ( $keywords );
$q = $search->getQuery ( $keywords );
echo '解析后的语句:' , var_export($q), $breakline;
if ($count <= 0)
throw new Exception('not found ') ;
$q = $search->terms() ; // 获取输入的关键词的高亮词列表
echo '高亮词条:' , var_export($q), $breakline;
$ids = array ();
$offset = 0;
$limit = 50; // 每次规定获取数量
for($i = 0, $c = $count / $limit; $i < $c; $i ++) {
// 获取数据
$docs = $search->setLimit( $limit, $offset )->search ();
foreach ( $docs as $v ) {
$iter = $v->getFields ();
$ids [] = array(
'id' => $iter ['pid'] ,
'name' => $search->highlight($iter['title'])
);
}
$_cc = count ( $ids ); // 统计当期已经查到的产品数量
$offset = $_cc;
}
var_dump ( $ids );
} catch ( Exception $e ) {
echo $e->getMessage ();
}
?>
</Pre>
</body>
</html>
查询语句简介
1.智能搜索
$docs = $search->setFuzzy()->setQuery(‘法国日本’)->setLimit(20)->search();
2.指定字段查询
$docs = $search->setFuzzy()->setQuery('title:法国日本')->setLimit(20)->search();
$docs = $search->setFuzzy()->setQuery('法国 OR 日本')->setLimit(20)->search();
$docs = $search->setFuzzy()->setQuery('法国 AND 日本')->setLimit(20)->search();
$docs = $search->setFuzzy()->setQuery('title:法国 AND title:日本')->setLimit(20)->search();
$docs = $search->setFuzzy()->setQuery('title:法国 OR title:日本')->setLimit(20)->search();
$docs = $search->setFuzzy()->setQuery('title:法国 XOR title:日本')->setLimit(20)->search(); // 表示必须包含其中一个词,并且不允许同时包含这两个词。
$docs = $search->setFuzzy()->setQuery('(des_city:巴黎 OR des_country:日本) AND title:日本巴黎')->setLimit(20)->search(); // 混合条件
$docs = $search->setFuzzy()->setQuery('title:巴黎 NOT title:服务')->setLimit(20)->search(); // 混合条件
3.AND 与 OR 不同
AND 为与关系,两个条件需同时为真,如 title:巴黎 AND title:服务 表示标题包含“巴黎”,并且包含“服务”
OR 为或关系,两个条件只需一个为真,如 title:巴黎 OR title:服务 表示标题包含“巴黎”或者“服务”
4.使用双引号精确匹配
$docs = $search->setQuery(‘title:“自由行香港”’)->setLimit(20)->search();
使用 addWeight 为排序加权
$docs = $search->setQuery(‘title:一日游’)->addWeight(‘des_city’,‘京都’)->setLimit(20)->search();
调用分词程序
例:
$xunsearch = new Xunsearch ();
$xs = $xunsearch->XS ( 'product' ); // 这里只进行分词,加载哪个配置文件不重要
$xt = new XSTokenizerScws() ;
$ret = $xt->getResult($keywords);
关键词高亮显示
调用 highlight 函数可以使字段中的关键词高亮
调用 terms 可以获取将被高亮的词条
例:
foreach ( $docs as $v ) {
$iter = $v->getFields ();
$ids [] = array(
'id' => $iter ['pid'] ,
'name' => $search->highlight($iter['title']) ,
'des_country' => $search->highlight($iter['des_country']) ,
'des_city' => $search->highlight($iter['des_city']) ,
);
}
建立索引
XSIndex 类为索引管理类
主要函数:
public XSIndex beginRebuild() // 开始重建索引
开始重建索引此后所有的索引更新指令将写到临时库, 而不是当前搜索库, 重建完成后调用 endRebuild 实现平滑重建索引, 重建过程仍可搜索旧的索引库, 如直接用 clean 清空数据, 则会导致重建过程搜索到不全的数据
public XSIndex clean() // 清空索引
public bool flushIndex() // 强制刷新索引库
public XSIndex endRebuild() // 完成并关闭重建索引, 重建完成后调用, 用重建好的索引数据代替旧的索引数据
public XSIndex add(XSDocument $doc) // 添加文档到索引
public XSIndex update(XSDocument $doc, bool $add=false) // 根据主键更新索引
更新索引文档该方法相当于先根据主键删除已存在的旧文档, 然后添加该文档如果你能明确认定是新文档, 则建议使用 add
自定义词
敏感词过滤