在Yii2.0 中怎么使用 sphinx 搜索

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Yii2.0 中怎么使用 sphinx 搜索相关的知识,希望对你有一定的参考价值。

参考技术A 如何调用Sphinx

按上面配置,第5节点对数据库进行了索引,通过Sphinx自带的search(在bin/release目录)就可以在命令行进行搜索:

(搜索CGArt)
windows上:
search -c d:/sphinx/sphinx.conf CGArt
Linux上:
cd /usr/local/sphinx
./bin/search -c sphinx.conf CGArt
运行后,系统提示一堆信息:
....
....
words:
1. 'cgart': 36 documents, 189 hits
这个表示库中有36条记录符合要求,出现CGArt的有189处。应用程序如果想调用Sphinx,可以从两个方面:

一是通过Sphinx官方提供的API接口(接口有Python,Java,php三种版本)

二是通过安装SphinxSE(具体见1.2部分),然后创建一个中介sphinxSE类型的表,再通过执行特定的SQL语句实现。

通过官方API调用Sphinx(以PHP为例)

在sphinx安装目录有一个API目录,里面有三个PHP文件:test.php,test2.php和sphinxapi.php。 sphinxapi.php是sphinx调用接口封装文件,test.php是一个在命令行下执行的查询例子文件,test2.php是一个生成摘要的 例子文件。

在命令下行运行test.php(Linux上没有API目录,需要从源程序包中复制api目录至/usr/local/sphinx)

Windows上:
D:\sphinx\bin\release>c:\php5.2\php.exe -c c:\php5.2\php.ini ..\..\api\test.php -i cgfinal CGartLinux上(php在/usr/local/php目录,sphinx.conf在/usr/local/sphinx目录):

cd /usr/local/sphinx
/usr/local/php/bin/php api/test.php -i cgfinal CGArtSphinx的API查询接口主要有这些内容(其实对照 一下sphinxapi.php就清楚了):

//创建Sphinx的客户端接口对象
$cl = new SphinxClient ();

//设置连接Sphinx主机名与端口
$cl->SetServer('localhost',3312);

//可选,为每一个全文检索字段设置权重,主要根据你在sql_query中定义的字段的顺序,Sphinx系统以后会调整,可以按字段名称来设定权重
$cl->SetWeights ( array ( 100, 1 ) );

//设定搜索模式,SPH_MATCH_ALL,SPH_MATCH_ANY,SPH_MATCH_BOOLEAN,SPH_MATCH_EXTENDED,SPH_MATCH_PHRASE
$cl->SetMatchMode(SPH_MATCH_ALL);

//设定过滤条件$attribute是属性名,相当于字段名(用SPH_MATCH_EXTENDED时),$value是值,$exclude是布尔型,
当为true时,相当于$attribute!=$value,默认值是false
$cl->SetFilter($attribute, $values, $exclude);

//设定group by
//根据分组方法,匹配的记录集被分流到不同的组,每个组都记录着组的匹配记录数以及根据当前排序方法本组中的最佳匹配记录。
//最后的结果集包含各组的一个最佳匹配记录,和匹配数量以及分组函数值
//结果集分组可以采用任意一个排序语句,包括文档的属性以及sphinx的下面几个内部属性
//@id--匹配文档ID
//@weight, @rank, @relevance--匹配权重
//@group--group by 函数值
//@count--组内记录数量
//$groupsort的默认排序方法是@group desc,就是按分组函数值大小倒序排列
$cl->SetGroupBy($attribute, $func, $groupsort);

//设定order by的内容,第一个参数是排序方法名,值有
// SPH_SORT_RELEVANCE,SPH_SORT_ATTR_DESC,SPH_SORT_ATTR_ASC,SPH_SORT_TIME_SEGMENTS,SPH_SORT_EXTENDED
//$sortby的值如"HITS desc"
$cl->SetSortMode(SPH_SORT_EXTENDED, $sortby);

//set count-distinct attribute for group-by queries,$distinct为字符串
$cl->SetGroupDistinct ( $distinct );

//相当于mysql的limit $offset,$limit
$cl->SetLimits($start,$limit)

//$q是查询的关键字,$index是索引名称,当等于*时表查询所有索引

yii2中sphinx搜索 多条件选择搜索

案例要求,效果图

首先,你需要安装spinx,具体安装可以百度一份如何安装,网上有很多,就不说了,

那么,安装完成后,打开sphinx(即你所建的sphinx安装目录),

找到这个文件,sphinx/etc/csft_mysql.conf文件,

在编译器中,打开这个文件,修改sphinx的源文件,配置

改完配置后,停止sphinx服务,打开cmd,进入到你安装的sphinx安装目录中

建立索引,

索引建立成功,开启sphinx服务

在使用sphinx之前,你需要把sphinx/api/sphinxapi.php文件,复制一份,放到yii2的web中,

与你的入口文件保持同级,方便调用

创建控制器,

[html] view plain copy print ?
  1. <?php  
  2.   
  3. namespace frontend\\controllers;  
  4.   
  5. use Yii;  
  6. use app\\models\\Position;  
  7. //use yii\\data\\Pagination;//分页类  
  8.   
  9. use yii\\db\\Query;//搜索类  
  10.   
  11. class IndexController extends \\yii\\web\\Controller  
  12.   
  13.   
  14.     //下拉选项字段 搜索值  
  15.     public function actionSearch_val()  
  16.       
  17.         $set = Yii::$app->request->get('set','');//接收搜索类型  
  18.         $key = Yii::$app->request->get('key','');//接收值  
  19.         require ( "sphinxapi.php" );//引入类  
  20.         if(yii::$app->request->isAjax)  
  21.             //echo $key.$set;die;  
  22.             $cl = new SphinxClient ();  
  23.             $cl->SetServer ( '127.0.0.1', 9312);   
  24.             $cl->SetConnectTimeout ( 3 );  
  25.             $cl->SetArrayResult ( true );  
  26.                 if(empty($key))  
  27.                     $cl->SetMatchMode ( SPH_MATCH_FULLSCAN );  
  28.                 else  
  29.                     $cl->SetMatchMode ( SPH_MATCH_EXTENDED2 );  
  30.                     if($set == 1)  
  31.                         $key = $key;    
  32.                     else if($set == 2)  
  33.                         $key = '@post_tempt ' .$key;  
  34.                     else if($set == 3)  
  35.                         $key = '@ask_for ' .$key;    
  36.                        
  37.                   
  38.                 $res = $cl->Query ( $key, "mysql" );  
  39.                   
  40.                 if($res['total_found'] > 0)  
  41.                     $ids = [];  
  42.                     foreach ( $res['matches'] as $key => $row )   
  43.                         $ids[] = $row['id'];  
  44.                       
  45.                     $query = new Query();  
  46.                     $list = $query->select('j_id, post_tempt, ask_for')->from('job')->where(['in', 'j_id', $ids])->all();  
  47.                     //print_r($list);  
  48.                  else   
  49.                     $list = [];  
  50.                           
  51.                 Yii::$app->response->format = \\yii\\web\\Response::FORMAT_JSON;  
  52.                 return ['list' => $list ];  
  53.               
  54.         return $this->render('search2');  
  55.       
<?php

namespace frontend\\controllers;

use Yii;
use app\\models\\Position;
//use yii\\data\\Pagination;//分页类

use yii\\db\\Query;//搜索类

class IndexController extends \\yii\\web\\Controller


    //下拉选项字段 搜索值
    public function actionSearch_val()
    
        $set = Yii::$app->request->get('set','');//接收搜索类型
        $key = Yii::$app->request->get('key','');//接收值
        require ( "sphinxapi.php" );//引入类
        if(yii::$app->request->isAjax)
            //echo $key.$set;die;
            $cl = new SphinxClient ();
            $cl->SetServer ( '127.0.0.1', 9312); 
            $cl->SetConnectTimeout ( 3 );
            $cl->SetArrayResult ( true );
                if(empty($key))
                    $cl->SetMatchMode ( SPH_MATCH_FULLSCAN );
                else
                    $cl->SetMatchMode ( SPH_MATCH_EXTENDED2 );
                    if($set == 1)
                        $key = $key;  
                    else if($set == 2)
                        $key = '@post_tempt ' .$key;
                    else if($set == 3)
                        $key = '@ask_for ' .$key;  
                     
                
                $res = $cl->Query ( $key, "mysql" );
                
                if($res['total_found'] > 0)
                    $ids = [];
                    foreach ( $res['matches'] as $key => $row ) 
                        $ids[] = $row['id'];
                    
                    $query = new Query();
                    $list = $query->select('j_id, post_tempt, ask_for')->from('job')->where(['in', 'j_id', $ids])->all();
                    //print_r($list);
                 else 
                    $list = [];
                        
                Yii::$app->response->format = \\yii\\web\\Response::FORMAT_JSON;
                return ['list' => $list ];
            
        return $this->render('search2');
    

然后,在Views对应控制器的文件夹下,创建一个文件,search2.php [html] view plain copy print ?
  1. <?php  
  2.   
  3. use yii\\bootstrap\\ActiveForm;  
  4. use yii\\helpers\\Html;  
  5. use yii\\helpers\\Url;  
  6.   
  7. ?>  
  8. <form action="" method="get">  
  9.     <input type="hidden" name="_csrf" value="dkZkUVdiTl8lDxQCZip9Ky4eLx4mViIWQXALAQMMOR4BEQMOZVZ8aA==">  
  10.   
  11.     <div class="col-md-1">  
  12.         <select id="set">  
  13.             <option value="1">全部</option>  
  14.             <option value="2">标题</option>  
  15.             <option value="3">内容</option>  
  16.         </select>  
  17.     </div>  
  18.     <div class="col-md-3">  
  19.         <input type="text" class="form-control" placeholder="keyword" id="key">  
  20.     </div>  
  21.     <button type="button" class="btn btn-default">Search</button>  
  22. </form>  
  23.   
  24. <p>  
  25.   
  26. <div id="content"></div>      
  27.   
  28. <?php $this->beginBlock('index') ?>  
  29.   
  30. $(function()  
  31.     $('.btn-default').click(function()  
  32.         var set = $('#set').val();  
  33.         var key = $('#key').val();  
  34.         var url = '<?php echo Url::toRoute(['index/search_val'])?>';  
  35.   
  36.         $.getJSON(url, 'key':key, 'set':set, function(data)  
  37.             //alert(data);  
  38.             console.log(data);  
  39.             var listsdata.list;  
  40.             //console.log(data.length)  
  41.               
  42.             var html = '<table class="table">';//这里用的是拼接  
  43.             for(var i = 0; i < lists.length; i++ )   
  44.                 html += '<tr>';  
  45.                 html += '<td>'+lists[i].j_id+'</td>';  
  46.                 html += '<td>'+lists[i].post_tempt+'</td>';  
  47.                 html += '<td>'+lists[i].ask_for+'</td>';  
  48.                 html += '</tr>';  
  49.                
  50.             html += '</table>';  
  51.             $('#content').html(html);  
  52.               
  53.         );  
  54.     );  
  55. );  
  56. <?php $this->endBlock('index') ?>  
  57. <?php $this->registerJs($this->blocks['index'], \\yii\\web\\View::POS_END);?>  
<?php

use yii\\bootstrap\\ActiveForm;
use yii\\helpers\\Html;
use yii\\helpers\\Url;

?>
<form action="" method="get">
	<input type="hidden" name="_csrf" value="dkZkUVdiTl8lDxQCZip9Ky4eLx4mViIWQXALAQMMOR4BEQMOZVZ8aA==">

	<div class="col-md-1">
		<select id="set">
			<option value="1">全部</option>
			<option value="2">标题</option>
			<option value="3">内容</option>
		</select>
	</div>
	<div class="col-md-3">
		<input type="text" class="form-control" placeholder="keyword" id="key">
	</div>
	<button type="button" class="btn btn-default">Search</button>
</form>

<p>

<div id="content"></div>	

<?php $this->beginBlock('index') ?>

$(function()
	$('.btn-default').click(function()
		var set = $('#set').val();
		var key = $('#key').val();
		var url = '<?php echo Url::toRoute(['index/search_val'])?>';

		$.getJSON(url, 'key':key, 'set':set, function(data)
			//alert(data);
			console.log(data);
			var lists= data.list;
			//console.log(data.length)
			
			var html = '<table class="table">';//这里用的是拼接
			for(var i = 0; i < lists.length; i++ ) 
				html += '<tr>';
				html += '<td>'+lists[i].j_id+'</td>';
				html += '<td>'+lists[i].post_tempt+'</td>';
				html += '<td>'+lists[i].ask_for+'</td>';
				html += '</tr>';
			 
			html += '</table>';
			$('#content').html(html);
			
		);
	);
);
<?php $this->endBlock('index') ?>
<?php $this->registerJs($this->blocks['index'], \\yii\\web\\View::POS_END);?>
这样就完成了,试一下效果:

完成!


以上是关于在Yii2.0 中怎么使用 sphinx 搜索的主要内容,如果未能解决你的问题,请参考以下文章

php中使用sphinx搜索引擎

PHP中使用Sphinx中文全文检索/搜索

`@geodist` 如何在 Sphinx 中实现排序/搜索?

Sphinx + Coreseek 实现中文分词搜索

Sphinx + Coreseek 实现中文分词搜索

Sphinx + Coreseek 实现中文分词搜索