• PHP-从零开始使用Solr搜索引擎服务(下)


    前言:

    原文地址:

    http://www.cnblogs.com/JimmyBright/p/7156085.html

    前面在配置完成Solr服务之后,在浏览器上可以打开Solr的管理界面,这个界面几乎包含了Solr的所有功能,如何反应到我们的PHP里边呢?很多人或许查到需要再安装一个php-solr-client,用于php和java的solr服务器通信,研究了半天没弄明白怎么做,反正是很麻烦而且似乎很多余。

    1:思路:

    注意看Solr的管理界面上,你或许有以下发现。

    上面框框中有一个url地址,把这个地址复制,然后放在浏览器的地址栏,果然如所想一样,返回了结果集。市面上有很多Solr教程,厚厚的一本书,里边讲解肯定很全面,我们没时间看,怎么能最快解决问题就怎么做。

    只要浏览器上能出结果,很自然就想到,Solr这是对外公开了一套api嘛,我们完全可以用php的curl做到这一点,浏览器能做到的,curl肯定也可以。

    这里写了一个简单的CURL请求方法

        private  function getCurl($url){
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL,$url);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $data = curl_exec($curl) ;
            curl_close($curl);
            return json_decode($data,true);
        }

    实验一下,和预期的结果完全一样,所以下面我们就用这个思路去对接php和solr。

    2:使用PHP操作Solr查询

    对应Solr管理界面上的Query栏目下,我们要搞清楚这些字段的意义,然后就能用php操作整个搜索过程了

    图中q、fq、sort、fl、df等,这些字段都是搜索用的字段,我们只要搞清楚这些字段意义就可以写php代码了。

    字段的意义网上有很多,这个链接都有介绍了

    http://blog.csdn.net/zmken497300/article/details/52817825

    3:使用PHP操作Solr建立索引
    搜索已经有思路去解决了,还有一个关键的问题要解决,Solr是对关联的数据库建立索引,再对索引进行搜索
    。很显然数据库任何时间都会变更,所以要让Solr能不间断的重建索引才能搜索到最新的结果集。
    管理界面中有一个Dataimport选项,点开可以手动重建索引,我们没有看到类似Query上的查询有一个
    URL,我们很希望有这一个东西,这样就能用curl,程序自动重建索引。
    按照前面的思路,我们有理由相信,Solr肯定已经有这样的api。
    把浏览器设置调试模式

    当我点下Execute按钮的时候,看到下面网络请求果然发出了一条url,复制这个url到浏览器,和想象的一样,自动重建了索引并返回了结果打印到浏览器上。

    到此为止,已经基本都解决了PHP操作Solr的技术问题,可以预见,完成一个简单的搜索功能,不会再出现技术问题了吧。

    下面附上一段PHP代码,操作Solr

     1 class SolrClient
     2 {
     3     public  $query_url='';
     4     public  $import_url='';
     5     private $q='q=*:*';
     6     private $fq='';
     7     private $sort='';
     8     private $rows='rows=10&start=0';
     9     private $fl='';
    10     private $raw_query='';
    11     public  $hl_str='';
    12 
    13     function  __construct($core)
    14     {
    15         $host=Yii::$app->params['solr_host'];
    16         $this->query_url=sprintf("%s/solr/%s/select?indent=on&wt=json&",$host,$core);
    17         $this->import_url=sprintf("%s/solr/%s/dataimport?indent=on&wt=json&command=full-import&verbose=false&clean=true&commit=true&optimize=false&core=crm&name=dataimport",$host,$core);
    18     }
    19     public function setQuery(array $query){
    20         $q_str=[];
    21         foreach ($query as $k=>$v) {
    22             if(!empty($v)){
    23                 $q_str[]=urlencode($k).':'.urlencode($v);
    24             }
    25         }
    26         if(!empty($q_str)){
    27             $this->q='q='.implode(urlencode(' OR '),$q_str);
    28         }
    29     }
    30     public function setFilterQuery(array $query){
    31         $q_str=[];
    32         foreach ($query as $k=>$v) {
    33             $q_str[]='fq='.urlencode($k).':'.urlencode($v);
    34         }
    35         $this->fq=implode('&',$q_str);
    36     }
    37     public function setRows($start,$rows){
    38         $this->rows=sprintf('rows=%s&start=%s',$rows,$start);
    39     }
    40     public function setHighLight(array $fields,$hlpre,$hlpost){
    41         $hl_fl=[];
    42         foreach ($fields as $field) {
    43             $hl_fl[]=$field;
    44         }
    45         $this->hl_str=sprintf("hl.fl=%s&hl.simple.post=%s&hl.simple.pre=%s&hl=on",implode(',',$hl_fl),urlencode($hlpost),urlencode($hlpre));
    46     }
    47     public function setFl(array $fields){
    48         $hl_fl=[];
    49         foreach ($fields as $field) {
    50             $hl_fl[]=$field;
    51         }
    52         $this->fl='fl='.implode(',',$hl_fl);
    53     }
    54     public function setRawQuery(array $params){
    55         $raw=[];
    56         foreach ($params as $k=>$v) {
    57             $raw[]=$k.'='.$v;
    58         }
    59         $this->raw_query=implode('&',$raw);
    60     }
    61     public function sortQuery($field,$sort){
    62         $this->sort= "sort=".$field.urlencode(' ').$sort;
    63     }
    64 
    65     /**
    66      * 搜索查询
    67      * @return mixed
    68      */
    69     public function search(){
    70         $this->query_url.=$this->q;
    71         !empty($this->fq)&&$this->query_url.='&'.$this->fq;
    72         !empty($this->sort)&&$this->query_url.='&'.$this->sort;
    73         !empty($this->rows)&&$this->query_url.='&'.$this->rows;
    74         !empty($this->fl)&&$this->query_url.='&'.$this->fl;
    75         !empty($this->raw_query)&&$this->query_url.='&'.$this->raw_query;
    76         !empty($this->hl_str)&&$this->query_url.='&'.$this->hl_str;
    77         return $this->getCurl($this->query_url);
    78     }
    79 
    80     /**
    81      * 全量重构索引
    82      * @return mixed
    83      */
    84     public  function index(){
    85         return $this->getCurl($this->import_url);
    86     }
    87     private  function getCurl($url){
    88         $curl = curl_init();
    89         curl_setopt($curl, CURLOPT_URL,$url);
    90         curl_setopt($curl, CURLOPT_HEADER, 0);
    91         curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    92         $data = curl_exec($curl) ;
    93         curl_close($curl);
    94         return json_decode($data,true);
    95     }
    96 
    97 }
    View Code

    search方法就是用来发起CURL的搜索命令,当然在这之前,你需要使用其他方法设置你的查询条件什么的。

    index方法就是用来发起CURL的重建索引命令,把这个方法放在crontab 定时任务里,就可以定时重建索引,我这里是全量重建索引,如果你的数据量很大,对新内容的搜索时效性也要求很高,那么可以使用增量索引,怎么做呢?看下管理界面,操作一下,然后调试模式抓取发出的请求连接,简单吧。

    结束:

    至此,就可以完成一个企业级的搜索服务了,下面贴上我给前端写的一个搜索接口,仅供参考!

     1  public function actionSearch(){
     2         $input = $this->getParam('input');
     3         $page  = $this->getParam('page')-1;
     4         empty($page)&&$page=0;
     5         $pageLength=200;
     6         $page<0&&$page=0;
     7         $startRow = $page*$pageLength;
     8         $params=['content_txt'=>$input,'title'=>$input];
     9         $solr = new SolrClient('crm');
    10         $solr->setQuery($params);
    11         $solr->setRows($startRow,$pageLength);
    12         $solr->setFl(['id','title','create_time','content','content_txt','keyword','description','sid','mask_status','type','article_type','item_type','sequence']);
    13         $solr->setHighLight(['title','content_txt'],"<b style='color: #f15353;'>","</b>");
    14         $data = $solr->search();
    15         $response=&$data['response'];
    16         $highlighting=&$data['highlighting'];
    17         $docs = &$response['docs'];
    18         empty($docs) && $this->jsonReturn(0,'搜索成功',['totalpage'=>0,'totalcount'=>0,'pagesize'=>$pageLength, 'list'=>[]]);
    19         foreach ($docs as &$doc) {
    20             $id = $doc['id'];
    21             $hlItem = $highlighting[$id];
    22             $doc['content']=mb_substr($doc['content_txt'],0,200);
    23             if(!empty($hlItem)){
    24                 if(!empty($hlItem['title'])){
    25                     if(!empty($hlItem['title'][0])){
    26                         $doc['title']=$hlItem['title'][0];
    27                     }
    28                 }
    29                 if(!empty($hlItem['content_txt'])){
    30                     if(!empty($hlItem['content_txt'][0])){
    31                         $doc['content']=$hlItem['content_txt'][0];
    32                     }
    33                 }
    34             }
    35             unset($doc['content_txt']);
    36         }
    37         $res=[
    38             'totalpage'=>ceil($response['numFound']/$pageLength),
    39             'totalcount'=>$response['numFound'],
    40             'pagesize'=>$pageLength,
    41             'list'=>$response['docs'],
    42         ];
    43         $this->jsonReturn(0,'搜索成功。',$res);
    44     }
    View Code

    然后附上一个简单粗糙的demo页面

  • 相关阅读:
    再提一个建议,不过就要辛苦dudu了
    项目中的小项目实现在望
    Visual Studio.Net 技术Tip
    IQueryable与foreach的困惑?
    [转贴]浅析大型网站的架构
    [原创]WCF入门级使用教程(转载请注明出处)
    [原创]在msmq3.0中使用http协议发送消息
    [转贴][WCF Security] 4. 用户名/密码身份验证
    [转贴][WCF Security] 1. 基本概念
    [转]在SQL Server2005中进行错误捕捉
  • 原文地址:https://www.cnblogs.com/JimmyBright/p/7156085.html
Copyright © 2020-2023  润新知