solr安装以及php调用

背景:项目中需要将原有的sphinx搜索引擎换成solr,以下是通过参照网络内容后,从搭建到调用的一次整理。

资源:http://blog.csdn.net/lynnlovemin/article/details/12103343   solr部署到服务器tomcat中(服务器上的jdk和tomcat已经配置好)

            http://www.php.net/manual/zh/class.solrquery.php  solr扩展方式调用参照

            http://wiki.apache.org/solr/CommonQueryParameters#q  solr客户端代码调用参照

            https://code.google.com/p/solr-php-client/downloads/list  solr客户端调用需要下载的文件包地址

            http://www.solr.cc/blog/  solr中国社区    官方QQ群:187670960

一.在服务器上将solr部署到tomcat中

主要步骤如下:

1、下载solr-4.4.0.tgz

2、解压缩solr-4.4.0.tgz,命令tar -xzvf solr-4.4.0.tgz

3、压缩后进入到solr-4.4.0目录,将 example/ webapps目录下的solr.war复制到tomcat的webapps目录中,

4、启动tomcat服务器,这时候会报错,不用管它,war会自动解压缩

5、在tomcat的bin里面新建一个solr目录

6、继续到solr-4.4.0目录,将example/solr目录下的collection1目录和solr.xml复制到tomcat的bin目录下的solr目录

7、将example/lib/ext/下的所有jar包复制到tomcat/webapps/solr/WEB-INF的lib目录中

8、在tomcat/webapps/solr/WEB-INF/下新建一个classes目录,将example/resources下的文件复制到该classes目录中

9、修改web.xml文件,为:


    solr/home
    /home/liyi/solrtomcat/bin/solr
    java.lang.String
10、再次启动tomcat,浏览器输入:http://localhost:8080/solr就能看到solr的管理界面了。

二.php客户端调用服务器solr和通过安装solr的php扩展调用服务器solr的代码coding

1、首先将要用到的solr-php-client下载下来,放入到自己的php文件中(需要用到扩展方式还需装好扩展)

2、开始coding自己的代码,期间需要用的查询q,过滤fq,排序sort等参数说明可以见上面的资源

3、自己的php代码如下(已验证可用,代码包含了两种调用方式。代码有点长初版本没怎么优化,可以根据自己的需要ctrl+c后删除不需要的部分)

ping() ) {
            echo 'Solr service not responding.';
            exit;
        }
        return $solrSearcher;
    }
    
    /**
     * php通过solr扩展连接服务器端
     */
    public static function extention_solr_server()
    {
        $extention_solrconfig=array('hostname' => self::SOLR_HOST,'port'=>self::SOLR_PORT);
        try {
            $solrSearcher = new SolrClient($extention_solrconfig);
            $solrSearcher->ping();  //需要,不调用ping()的时候如果服务器连接不上不会抛异常
        } catch (Exception $e) {
            echo "Solr extention service connect fail.";
            exit;
        }
        return $solrSearcher;
    }
     
    /**
     * php文件包方式查询方法
     */
    public static function solr_query($query,$pageinfo=array('offset'=>0,'limit'=>600),
        $params=array('fl'=>'','fq'=>array())){
        $solrSearcher=self::solr_server();
        
        $params['fl']=$params['fl']?$params['fl'].",score":"*,score";
        $response = $solrSearcher->search( $query , $pageinfo['offset'], $pageinfo['limit'] ,$params);
        
        $result=array();
        $found_num=0;
        $http_status=$response->getHttpStatus();
        
        if ( $http_status == 200 ) {
            $response_result=$response->response;
            $found_num=$response_result->numFound;
            
            if ( $found_num > 0 ) {
                $search_docs=$response_result->docs;
                $highlighting=$response->highlighting;
                foreach ($search_docs as $s_k=>$s_v){
                    $lists=get_object_vars($s_v->getIterator());
                    $lists['goods_color_name']=empty($highlighting->$lists['goods_id']->goods_name[0]) ? $lists['goods_name'] : $highlighting->$lists['goods_id']->goods_name[0];
                    $result['lists'][]=$lists;
                }
            }
            $result['total']=$found_num;
            $result['goods_status']=array();
            $result['total_found']=$found_num;
        }
        else {
          echo $response->getHttpStatusMessage();
        }
        
        return $result;
    }
    
    /**
     * 获取关键字分词后形成的词
     */
    public static function getWords($keyword)
    {
        $keyword = trim($keyword);
        $words = array();
        if ($keyword)
        {
            $wordsInfo = self::getWordsInfo($keyword);
            if (is_array($wordsInfo) && !empty($wordsInfo))
            {
                foreach ($wordsInfo as $val)
                {
                    $words[] = $val['text'];
                }
            }
        }
        return $words;
    }
    
    /**
     * 获取关键字分词后的信息
     */
    public static function getWordsInfo($keyword)
    {
        $keyword = urlencode($keyword);
        
        // 拼接 调用分词接口的url
        $url = "http://172.18.107.96:8888/solr/collection1/analysis/field?wt=json&analysis.showmatch=true&analysis.fieldvalue=".$keyword."&analysis.fieldname=MaxWord&_=".time();
        $i = 0;               // 记录查询失败的次数
        $code = 0;            // 记录查询状态
        $responseStr = "";    // 接口返回json字符串
        while($code == 0 && $i < 5)  //查询失败重试
        {
            $ch=curl_init();                    
            curl_setopt($ch,CURLOPT_URL,$url); 
            curl_setopt($ch,CURLOPT_HEADER,0); 
            curl_setopt($ch,CURLOPT_TIMEOUT,10);
            curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
            
            $responseStr = curl_exec($ch);
            $code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
            $i += $code ? 0 : 1;    //失败则查询次数加1
            curl_close($ch);
        }
        
        // 解析接口返回的字符串 获取分词信息以数组形式保存
        if ($responseStr)
        {
            $responseArr = json_decode($responseStr,true);
            if (isset($responseArr['analysis']['field_names']['MaxWord']['index']))
            {
                return $responseArr['analysis']['field_names']['MaxWord']['index'][1];
            }
        }
        return array();
    }
    
    /**
     * 将收集到查询条件转换成solr要用到的信息 进行solr搜索
     */
    public static function find($conditions = array())
    {
        // 定义存储 solr应用中q查询操作信息 $q = "goods_name:红色帽子 OR price:30";(对象包含关键字,一二级分类,属性)
        $q = "";
        if (empty($_GET['keyword']))
        {
            $q .= "goods_name:*";
        }
        else
        {
            $q .= "goods_name:".$_GET['keyword'];
        }
        
        // 拼接分类条件信息
        if (!empty($conditions['select']))
        {
            if ($conditions['select'] == 1)
            {
                $q .= " AND cate_id_1:".$conditions['filter']['cate_id_1'][0];
            }
            else if ($conditions['select'] == 2)
            {
                $q .= " AND cate_id_2:".$conditions['filter']['cate_id_2'][0];
            }
        }
        
        // 拼接属性条件信息
        if (!empty($_GET['g']))    // [g] => 2966_15449-2961_3007
        {
            $attr_id_arr = explode('-', $_GET['g']);
            
            foreach ($attr_id_arr as $val)
            {
                $arr = explode('_', $val);
                $q .= " AND attr_id:*".$arr[1]."*";
            }
        }
        
        // 判断扩展方式是否可用,决定调用的方式
        if (class_exists('SolrClient'))    // 通过solr的php扩展方式进行solr的连接处理
        {
            $client = self::extention_solr_server();
            $query = new SolrQuery();
            // 设置sorl查询的q信息
            //$query->setQuery('goods_name:红色帽子');
            $query->setQuery($q);
            // 设置获取结果的起始位置
            $query->setStart(0);
            // 设置获取结果的记录数
            $query->setRows(600);        // 类似分页的取出记录条数
            // 设置排序信息SolrQuery::ORDER_ASC ,SolrQuery::ORDER_DESC
            //$query->addSortField("goods_id",SolrQuery::ORDER_DESC);    
            // 设置sorl查询的fq信息
            $fqInfo = self::getFqInfo($conditions,$query);
            if (!empty($fqInfo))
            {
                $query = $fqInfo;
            }
    
            $queryResponse = $client->query($query);
            $response = $queryResponse->getResponse();
            if ( $response->responseHeader->status == 0 ) {
                $response_result=$response->response;
                $found_num=$response_result->numFound;
                
                if ( $found_num > 0 ) {
                    $search_docs=$response_result->docs;
                    $highlighting=$response->highlighting;
                    
                    foreach ($search_docs as $s_k=>$s_v){
                        // $lists=get_object_vars($s_v->getIterator());
                        $lists=json_decode(json_encode($s_v),true);
                        $lists['goods_color_name']=empty($highlighting->$lists['goods_id']->goods_name[0]) ? $lists['goods_name'] : $highlighting->$lists['goods_id']->goods_name[0];
                        $result['lists'][]=$lists;
                    }
                }
                $result['total']=$found_num;
                $result['goods_status']=array();
                $result['total_found']=$found_num;
            }
            else {
              echo $response->getHttpStatusMessage();
            }
            $data = $result;
        }
        else    // 通过solr的php文件包方式进行solr的连接处理
        {
            // 定义存储 solr应用中排序sort,过滤查询fq,返回结果字段fl等信息 的数组
            $params = array();
            $params['fl'] = "";
            //$params['sort'] = $conditions['order'];  //权重分字段没有,暂时注释
            $params['sort'] = "goods_id desc";

            // 定义高亮显示参数(有关键字时将关键字高亮)
            if (!empty($_GET['keyword']))
            {
                 $params['hl'] = "true";
                 $params['hl.fl'] = "goods_name";
                 $params['hl.simple.pre'] = "";
                 $params['hl.simple.post'] = "";
            }
            
            // 定义存储fq过滤信息数组,每个字段的条件设置作为数组$fq一个元素(包含)
            $fq = self::getFqInfo($conditions);
            if (!empty($fq))
            {
                $params['fq'] = $fq;
            }

            // 用拼接好的参数调用solr查询
            $data = self::solr_query($q,array('offset'=>0,'limit'=>600),$params);
        }
        
        // clear参数为7打印语句
        if ($_GET['clear'] == 7)
        {
            echo "
";print_r($data);exit;
        }
        
        // 将关键字信息存入data数据中
        $data['words']=self::getWords($_GET['keyword']);
        return $data;
    }
    
    /**
     * 
     * 依照前台处理后的条件数据转换成solr查询应用的过滤fq信息
     * $query object 区别当前是以php文件包的方式还是扩展的方式调用solr(默认是php文件包方式,$query不为null则是扩展方式)
     * @param array $conditions
     */
    private static function getFqInfo($conditions,$query=null)
    {
        // 定义前台传递参数与solr应用参数之间的key对应关系(其中数组key为前台key,数组val为solr应用key)
        $solr_key=array(
                'price'=>'price',                                // 价格
                'return_goods_status'=>'return_goods_status',    // 48小时包退包换
                'if_free_shipping'=>'if_free_shipping',          // 免运费字段
                'if_new_goods'=>'if_new_goods',                  // 新品
                'real_shot'=>'real_shot',                        // 实拍
                'is_enterprise'=>'is_enterprise',                // 企业身份认证
                'is_entity'=>'is_entity',                        // 实体认证
                'is_behalfof'=>'is_behalfof',                    // 一件代发
                'is_specialmem_status'=>'is_specialmem_status',  // 免费看样
                'is_promise'=>'is_promise',                      // 店铺等级
                //'minbuy'=>'minbuy',                              // 起批数量
                //'minbuyprice'=>'minbuyprice',                    // 起批价格
        );
        
        // 定义通过solr的php文件包形式调用solr服务器时fq信息存储数组
        $fq = array();
        
        // 当前台页面传递过来的参数中包含过滤条件时,依照不同的调用方式解析成solr应用的过滤fq信息
        if (!empty($conditions['filter']))
        {
            foreach ($conditions['filter'] as $key=>$val)
            {
                $fq_info_str = "";
                if (array_key_exists($key, $solr_key))
                {
                    if ($key == "price")
                    {
                        $minPrice = strval(empty($val['min']) ? 0 : $val['min']);
                        $maxPrice = strval(empty($val['max']) ? "*" : $val['max']);
                        $fq_info_str = "price:[".$minPrice." TO ".$maxPrice."]";
                    }
                    else
                    {
                        if (is_array($val))
                        {
                            $fq_info_str = $solr_key[$key].":".$val[0];
                        }
                        else
                        {
                            $fq_info_str = $solr_key.":".$val[0];
                        }
                    }
                }
                
                /* $query不为null时,此时通过solr的php扩展方式调用solr服务器,fq信息通过$query->addFilterQuery("price:30");添加
                 * $query为null时,此时通过solr的php文件包调用solr服务器,fq信息通过$fq[] = "price:30";添加
                 */
                if ($fq_info_str != "")
                {
                    if ($query != null)
                    {
                        $query->addFilterQuery($fq_info_str);
                    }
                    else
                    {
                        $fq[] = $fq_info_str;
                    }
                }
            }
            
            // 依照调用方式的不同返回不同的值
            if ($query != null)
            {
                return $query;
            }
            else
            {
                return $fq;
            }
        }
        else
        {
            return ;
        }
    }
}
三.php的solr扩展安装

1.安装扩展前,先安装libxml2(可以谷歌下安装过程)。安装过程中在make的时候有时候会报错,这时候可以运行下make clean命令就可以了,详细的见http://www.cnblogs.com/wanhl/archive/2013/03/19/2969758.html

2.安装扩展内容(下面内容)可以查看:http://www.cnblogs.com/AndreMouche/archive/2011/07/31/2122872.html

libxml2 2.6.31或以上版本
libcurl 7.18.0 或以上版本
到php官网下载solr: http://pecl.php.net/package/solr
然后:
/usr/local/php5/bin/phpize
./configure --with-php-config=/usr/local/php5/bin/php-config
sudo make
sudo make test
sudo make install

安装完后会有类似这样的提示:
Installing shared extensions:         /usr/local/lib/php/extensions/no-debug-non-zts-20090626/
把这个记住,然后修改php.ini(vim /usr/local/etc/php.ini ),把
extension_dir = "./"
修改为
extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/"

并添加一行
extension=solr.so
注意:/usr/local/php5/bin/phpize 可能会出现变化,具体根据php的安装位置而定。

四、安装solr扩展

下载资源   wget "http://pecl.php.net/get/solr-2.0.0.tgz"

解压  tar zxvf solr-2.0.0.tgz

进入解压后目录 cd solr-2.0.0

运行  

phpize

./configure

make install

在/etc/php.d下随便复制一个扩展的文件,把里面加载的扩展改成solr.so。重启php-fpm加载solr扩展:service php-fpm reload

补充上面的



你可能感兴趣的:(php扩展)