深入解析php之sphinx,学习笔记整理
分类:web前端

<?php
//参数筛选

sphinx安装,配置,使用,分页

Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能

//筛选cat_id=2
$cl->SetFilter("cat_id",array(2));
//仅在id为1、3、7的子论坛中搜索
$cl->SetFilter("forum_id",array(1,3,7));

  1. Sphinx简介

sphinx 安装

//范围筛选
//筛选发布时间为今天,参数为int时间戳
$cl->SetFilterRange("starttime",123,124);
//筛选价格
$cl->SetFilterRange("price",10.0,99.9);

 

Sphinx在mysql上的应用有两种方式:

// 分组
//按照item_id分组,并且按照order desc排序
$cl->SetGroupBy("item_id",SPH_GROUP_ATTR,"order desc");

SQL   结构化查询语言(是一种标准,所有的关系型数据库Mysql,sqlserver,oracle)

1.    采用API调用,如使用PHP、java等的API函数或方法查询。优点是可不必对mysql重新编译,服务端进程“低耦合”,且程序可灵活、方便的调用;缺点是如已有搜索程序的条件下,需修改部分程序。推荐程序员使用。

//排序模式
//按照price desc排序
$cl->SetSortMode(SPH_SORT_ATTR_DESC,"price");
 注意:会被SetGroupBy中的排序覆盖

sphinx的使用两种方式:

2.    使用插件方式(sphinxSE)把sphinx编译成一个mysql插件并使用特定的sql语句进行检索。其特点是,在sql端方便组合,且能直接返回数据给客户端。不必二次查询,在程序上仅需要修改对应的sql,但这对使用框架开发的程序很不方便,比如使用了ORM。另外还需要对mysql进行重新编译,且需要mysql-5.1以上版本支持插件存储。

// 匹配查询词中的任意一个
$cl->SetMatchMode ( SPH_MATCH_ANY );
SPH_MATCH_ALL, 匹配所有查询词(默认模式);
SPH_MATCH_ANY, 匹配查询词中的任意一个;
SPH_MATCH_PHRASE, 将整个查询看作一个词组,要求按顺序完整匹配;
SPH_MATCH_BOOLEAN, 将查询看作一个布尔表达式 (参见 第 5.2 节 “布尔查询语法”);
SPH_MATCH_EXTENDED, 将查询看作一个CoreSeek/Sphinx内部查询语言的表达式 (参见 第 5.3 节 “扩展查询语法”). 从版本Coreseek 3/Sphinx 0.9.9开始, 这个选项被选项SPH_MATCH_EXTENDED2代替,它提供了更多功能和更佳的性能。保留这个选项是为了与遗留的旧代码兼容——这样即使 Sphinx及其组件包括API升级的时候,旧的应用程序代码还能够继续工作。
SPH_MATCH_EXTENDED2, 使用第二版的“扩展匹配模式”对查询进行匹配.
SPH_MATCH_FULLSCAN, 强制使用下文所述的“完整扫描”模式来对查询进行匹配。注意,在此模式下,所有的查询词都被忽略,尽管过滤器、过滤器范围以及分组仍然起作用,但任何文本匹配都不会发生.

 

这里的安装主要介绍的是第一种通过api调用的方式。Sphinx的安装如下:

//从0开始查询,查询30条,返回结果最多为1000
$cl->setLimits(0,30,1000);

第一种:  使用sphinx的API来操作sphinx   (常用)   

 代码如下

// 从名称为index的sphinx索引查询“电影票”
$cl->Query("电影票","index");

 sphinx可以使用API类,也可以将api编译到PHP中做为扩展

复制代码

// 从名称为index的sphinx索引查询“电影票”
$sp->SetGroupBy('item_id',SPH_GROUP_ATTR,'s_order desc');
$sp->SetFilter('city_id','1');
$sp->SetFilter('cat_id',array(1));
$sp->SetLimit(0,10,1000);
$sp->AddQuery('电影票','index');
$sp->ResetFilters();//重置筛选条件
$sp->ResetGroupBy();//重置分组

第二种:  使用mysql的sphinx的存储引擎

#下载最新稳定版

$sp->SetGroupBy('item_id', SPH_GROUPBY_ATTR, 's_order desc');
$sp->setFilter('city_id', '2');
$sp->setFilter('cat_id', array(2));
$sp->setLimits(0, 20, 1000);
$sp->AddQuery('温泉', 'index');
$sp->ResetFilters();// 重置筛选条件
$sp->ResetGroupBy();//重置分组
$results = $sp->RunQuries();
批量查询(或多查询)使searchd能够进行可能的内部优化,并且无论在任何情况下都会减少网络连接和进程创建方面的开销。相对于单独的查询,批量查询不会引入任何额外的开销。因此当您的Web页运行几个不同的查询时,一定要考虑使用批量查询。
例如,多次运行同一个全文查询,但使用不同的排序或分组设置,这会使searchd仅运行一次开销昂贵的全文检索和相关度计算,然后在此基础上产生多个分组结果。
有时您不仅需要简单地显示搜索结果,而且要显示一些与类别相关的计数信息,例如按制造商分组后的产品数目,此时批量查询会节约大量的开销。 若无批量查询,您会必须将这些本质上几乎相同的查询运行多次并取回相同的匹配项,最后产生不同的结果集。若使用批量查询,您只须将这些查询简单地组成一个 批量查询,Sphinx会在内部优化掉这些冗余的全文搜索。
AddQuery()在内部存储全部当前设置状态以及查询,您也可在后续的AddQuery()调用中改变设置。早先加入的查询不会被影响,实际上没有任何办法可以改变它们。

 

wget

用上述代码,第一个查询会在“documents”索引上查询“hello world”并将结果按相关度排序,第二个查询会在“products”索引上查询“ipod”并将结果按价格排序,第三个查询在“books”索引上搜 索“harry potter”,结果仍按价格排序。注意,第二个SetSortMode()调用并不会影响第一个查询(因为它已经被添加了),但后面的两个查询都会受影 响。
此外,在AddQuery()之前设置的任何过滤,都会被后续查询继续使用。因此,如果在第一个查询前使用SetFilter(),则通过 AddQuery()执行的第二个查询(以及随后的批量查询)都会应用同样的过滤,除非你先调用ResetFilters()来清除过滤规则。同时,你还 可以随时加入新的过滤规则
AddQuery()并不修改当前状态。也就是说,已有的全部排序、过滤和分组设置都不会因这个调用而发生改变,因此后续的查询很容易地复用现有设置。
AddQuery()返回RunQueries()结果返回的数组中的一个下标。它是一个从0开始的递增整数,即,第一次调用返回0,第二次返回1,以此类推。这个方便的特性使你在需要这些下标的时候不用手工记录它们。
?>

sphinx  这是英文的全文检索引擎

tar xzvf sphinx-0.9.9.tar.gz

coreseek  这是支持中文词库的全文检索引擎

cd sphinx-0.9.9

 

./configure --prefix=/usr/local/sphinx/   --with-mysql  --enable-id64

区别:

make

英文的文章 怎么能区分哪个词    以空格来区分词的

make install

中文的文章 我爱北京天安门      中文词库

注意:采用这种方式安装不支持中文分词。

 

三、  Sphinx中文分词中文的全文检索和英文等latin系列不一样,后者是根据空格等特殊字符来断词,而中文是根据语义来分词。中文分词主要有2个插件

使用sphinx的步骤:

1.    Coreseek

 

Coreseek是现在用的最多的sphinx中文全文检索,它提供了为Sphinx设计的中文分词包LibMMSeg ,是基于sphinx的基础上开发的。

2、sphinx配置(配置文件 csft_mysql.conf)

2.    sfc(Sphinx-for-chinese)

   配置文件格式

sfc(sphinx-for-chinese)是由网友happy兄提供的另外一个中文分词插件。其中文词典采用的是xdict。

1、数据源定义 (指向你数据的来源 ,通常是mysql)

本节主要介绍Coreseek的安装方法

    2、索引 (索引的一些配置信息)

四、  Coreseek(支持中文检索的sphinx)安装1.    安装升级autoconf

    3、indexer  (内用的内存---基本不需要设置)

因为coreseek需要autoconf 2.64以上版本,因此需要升级autoconf,不然会报错从

4、searchd  (服务器的一些配置---)

 代码如下

图片 1

复制代码

 

tar -jxvf autoconf-2.64.tar.bz2

   注意:

cd autoconf-2.64

1、一个配置文件可以配置多个数据源和索引 ((1,2),(1,2),nnnn)

./configure

2、sql_query  主查询(把数据库表中的哪些字段查询出来--根据你页面的搜索条件)

make

              select 第一个字段(一定是主键)

make install

 

2.    下载coreseek

  1. sphinx安装

新版本的coreseek将词典和sphinx源程序放在了一个包中,因此只需要下载coreseek包就可以了。

① cd E:/usr/local/coreseek-3.2.14-win32

wget

② indexer.exe -c 配置文件 --all(参数--all 表示创建全部索引)

3.    安装mmseg(coreseek所使用的词典)

.binindexer.exe -c .etccsft_mysql.conf --all

 代码如下

③ 启动searchd 服务  searchd.exe -c 配置文件

复制代码

.binsearchd.exe -c .etccsft_mysql.conf  如果启动服务出现1067错误后 查看配置文件 和配置文件的文字编码

tar xzvf coreseek-3.2.14.tar.gz

④ php 操作sphinx

cd mmseg-3.2.14

 

./bootstrap    #输出的warning信息可以忽略,如果出现error则需要解决

  1. Sphinx 的使用

./configure --prefix=/usr/local/mmseg3

use SphinxClient;

make && make install

/*引入sphinx类*/

cd ..

Yii::$classMap['SphinxClient']="@vendor/sphinx/sphinxapi.php";

4.    安装coreseek(sphinx)

//简单使用sphinx

 代码如下

$cl = new SphinxClient ();

复制代码

$cl->SetServer ( '127.0.0.1', 9312);

cd csft-3.2.14

$cl->SetMatchMode ( SPH_MATCH_ALL); //匹配格式  任意匹配

sh buildconf.sh    #输出的warning信息可以忽略,如果出现error则需要解决

SPH_MATCH_ALL匹配所有查询词(默认模式)
SPH_MATCH_ANY匹配查询词中的任意一个
SPH_MATCH_PHRASE将整个查询看作一个词组,要求按顺序完整匹配
SPH_MATCH_BOOLEAN将查询看作一个布尔表达式
SPH_MATCH_EXTENDED将查询看作一个Sphinx内部查询语言的表达式
SPH_MATCH_FULLSCAN使用完全扫描,忽略查询词汇
SPH_MATCH_EXTENDED2类似 SPH_MATCH_EXTENDED ,并支持评分和权重.

./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

        $cl->SetArrayResult ( true );  //作为数组返回

make && make install

        $cl->SetMaxQueryTime(10); //设置最大搜索时长

cd ..

        //$cl->SetFilter('cat_id', array(1));//过滤条件

5.    测试mmseg分词和coreseek搜索

        $cl->setSortMode(SPH_SORT_EXTENDED,'@id desc'); //排序

备注:需要预先设置好字符集为zh_CN.UTF-8,确保正确显示中文,我的系统字符集为en_US.UTF-8也是可以的。

 //$res=$cl->Query ( $req, "*" ); //执行搜索

 代码如下

        $res=$cl->Query($req, '*');//搜索全部

复制代码

  1. Sphinx 标红

cd testpack

$opt=array("before_match"=>"<font style='font-weight:bold;color:#f00'>","after_match"=>"</font>");

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

        //这里为sphinx高亮显示

/usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc var/test/test.xml

        foreach($data_arr as $k=>$v){

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

            $rows = $cl->buildExcerpts($v,"mysql",$req,$opt);

/usr/local/coreseek/bin/search -c etc/csft.conf

            $model_arr[$k]['id']=$rows[0];

网络搜索

            $model_arr[$k]['name']=$rows[1];

此时正确的应该返回

            $model_arr[$k]['cat_id']=$rows[2];

words:

 

  1. '网络': 1 documents, 1 hits

  2. '搜索': 2 documents, 5 hits

        }

6.    生成 mmseg词库及配置文件

【注意】:

新版本的已经自动生成。

语法:public array SphinxClient::buildExcerpts ( array $docs , string $index , string $words [, array $opt ] )

sphinx api 的完整用法及重要属性,整理一下,以防忘记!

 

 代码如下

可以有四个参数,前三个为必须

复制代码

array $docs    :     即从数据库取出来的结果数组(fetch_assoc),本实例为 $row ;

$cl = new SphinxClient ();
//安装的默认host:localhost  ,sphinx端口:3312
$cl->SetServer ( "localhost", "3312"); 
//可选,为每一个全文检索字段设置权重,主要根据你在sql_query中定义的字段的顺序,Sphinx系统以后会调整,可以按字段名称来设定权重.  可以参考SetFieldWeights(array ( 100, 1 )) 
$cl->SetWeights ( array ( 100, 1 ) );  
 
 
//查询的模式,总共有以下模式:SPH_MATCH_ALL,匹配所有查询词(and)(默认模式)SPH_MATCH_ANY, 匹配查询词中的任意一个(or)SPH_MATCH_PHRASE, 将整个查询看作一个词组,要求按顺序完整匹配SPH_MATCH_BOOLEAN, 将查询看作一个布尔表达式 SPH_MATCH_EXTENDED, 将查询看作一个 Sphinx 内部查询语言的表达式 。还有一个特殊的“完整扫描”模式,当如下条件满足时,该模式被自动激活:
//1. 查询串是空的(即长度为零)
//2.docinfo存储方式为 extern在完整扫描模式中,全部已索引的文档都被看作是匹配的。这类匹配仍然会被过滤、排序或分组,但是并不会做任何真正的全文检索。这种模式可以用来统一全文检索和非全文检索的代码,或者减轻SQL 服务器的负担(有些时候 Sphinx 扫描的速度要优于类似的 MySQL 查询)
$cl->SetMatchMode ( "SPH_MATCH_ALL" ); 
 
 //只搜索forum_id=1或3或7  如果$cl->SetFilter ( "forum_id", array ( 1,3,7 ) ,true); 表示只搜索forum_id!=1或!=2或!=7
$cl->SetFilter ( "forum_id", array ( 1,3,7 ) );
 
//SPH_GROUPBY_DAY,从时间戳中按 YYYYMMDD 格式抽取年、月、日 
//SPH_GROUPBY_WEEK,从时间戳中按 YYYYNNN 格式抽取年份和指定周数(自年初计起)的第一天 
//SPH_GROUPBY_MONTH,从时间戳中按 YYYYMM 格式抽取月份
//SPH_GROUPBY_YEAR,从时间戳中按 YYYY 格式抽取年份  //最终的搜索结果中每组包含一个最佳匹配。分组函数值和每组的匹配数目分别以“虚拟”属性@group 和@count 的形式返回。
//SPH_SORT_RELEVANCE忽略任何附加的参数,永远按相关度评分排序。所有其余的模式都要求额外的排序子句,子句的语法跟具体的模式有关。
$cl->SetGroupBy ("UserName", SPH_GROUPBY_ATTR, $groupsort );
 
$cl->SetGroupDistinct ( $distinct );
/*
$cl->SetGroupBy ( "category", SPH_GROUPBY_ATTR, "@count desc" );
$cl->SetGroupDistinct ( "vendor" );
相当于:
SELECT id, weight, all-attributes,
    COUNT(DISTINCT vendor) AS @distinct,
    COUNT(*) AS @count
FROM products
GROUP BY category
ORDER BY @count DESC
*/

string $Index   :    即我们在csft_mysql.conf 配置的索引名,本实例为 news

  
 
//SPH_SORT_RELEVANCE 模式, 按相关度降序排列(最好的匹配排在最前面)SPH_SORT_ATTR_DESC 模式, 按属性降序排列 (属性值越大的越是排在前面)SPH_SORT_ATTR_ASC 模式, 按属性升序排列(属性值越小的越是排在前面)SPH_SORT_TIME_SEGMENTS 模式, 先按时间段(最近一小时/天/周/月)降序,再按相关度降序SPH_SORT_EXTENDED 模式, 按一种类似 SQL 的方式将列组合起来,升序或降序排列。SPH_SORT_EXPR 模式,按某个算术表达式排序。

string $words  :    搜索的关键词,本实例为 $keyword

 代码如下

 

复制代码

可选参数 array $opts:它是一个索引数组,你可以定义其中的一些单元,

$cl->SetSortMode ( SPH_SORT_EXTENDED, "post_date");
 
//从第0个开始,取$limit 个,  第三个参数限制了最大偏移量不大于1000
$cl->SetLimits ( 0, $limit, ( $limit>1000 ) ? $limit : 1000 );  

 

 
//设置评分模式:    * SPH_RANK_PROXIMITY_BM25, 默认模式,同时使用词组评分和BM25评分,并且将二者结合。* SPH_RANK_BM25, 统计相关度计算模式,仅使用BM25评分计算(与大多数全文检索引擎相同)。这个模式比较快,但是可能使包含多个词的查询的结果质量下降。 * SPH_RANK_NONE, 禁用评分的模式,这是最快的模式。实际上这种模式与布尔搜索相同。所有的匹配项都被赋予权重1。* SPH_RANK_WORDCOUNT, 根据关键词出现次数排序。这个排序器计算每个字段中关键字的出现次数,然后把计数与字段的权重相乘,最后将积求和,作为最终结果。* SPH_RANK_PROXIMITY, 版本0.9.9-rc1新增,将原始的词组相似度作为结果返回。在内部,这个模式被用来模拟SPH_MATCH_ALL的查询。 * SPH_RANK_MATCHANY, 版本0.9.9-rc1新增,返回之前在SPH_MATCH_ANY中计算的位次,在内部这个模式用于模拟SPH_MATCH_ANY的查询。* SPH_RANK_FIELDMASK, 版本0.9.9-rc2新增,返回一个32位掩码,其中第N位对应第N个全文字段,从0开始计数,如果某个字段中出现了满足查询的关键词,则对应的标志位被置1。 

 代码如下

复制代码

$cl->SetRankingMode ( "SPH_RANK_PROXIMITY_BM25");
 
//PHP专用。控制搜索结果集的返回格式(匹配项按数组返回还是按hash返回)$arrayresult 参数应为布尔型。如果$arrayresult为false(默认),匹配项以PHP hash格式返回,文档ID为键,其他信息(权重、属性)为值。如果$arrayresult为true,匹配项以普通数组返回,包括匹配项的全部信息(含文档ID) 
$cl->SetArrayResult ( true );

  
 
//连接到searchd服务器,根据服务器的当前设置执行给定的查询,取得并返回结果集。$query是查询字串,$index是包含一个或多个索引名的字符串。一旦发生一般错误,则返回假并设置GetLastError()信息。若成功则返回搜索的结果集。此外, $comment 将被发送到查询日志中搜索部分的前面,这对于调试是非常有用的。目前,注释的长度限制为128个字符以内。$index的默认值是"*",意思是对全部本地索引做查询。索引名中允许的字符包括拉丁字母(a-z),数字(0-9),减号(-)和下划线(_),其他字符均视为分隔符。因此,下面的示例调用都是有效的,而且会搜索相同的两个索引: 

 代码如下

复制代码

$res = $cl->Query ( $query, $index );
/*
$cl->Query ( "test query", "main delta" );
$cl->Query ( "test query", "main;delta" );
$cl->Query ( "test query", "main, delta" );
*/

sphinx 安装 Sphinx在mysql上...

本文由10bet手机官网发布于web前端,转载请注明出处:深入解析php之sphinx,学习笔记整理

上一篇:深入分析php之面向对象,php5中类的学习 下一篇:没有了
猜你喜欢
热门排行
精彩图文