laravel solr使用PHP(Laravel)实现Solr全文搜索详细过程

一、安装 Solr

solr需要 Tomcat环境 所以我们需要先装 Tomcat,而安装tomcat之前需要先安装JDK,所以我们第一步就是先安装 JDK

1、安装 JDK

2、安装 Tomcat8

       Linux 可以安装在 :/usr/local/tomcat

       Windows 我是安装在了 D 盘下面 :D:\tomcat     
(windows的下载和设置 可以看 http://www.pc6.com/softview/SoftView_441381.html

3、安装 Solr

wget http://mirrors.hust.edu.cn/apache/lucene/solr/7.4.0/solr-7.4.0.tgz

       (1) Linux 解压到 opt 后进入 solr-7.4.0文件夹 ,把里面 server/solr-webapp 拷贝到 tomcat下的webapps里,并重命名为solr

cp -r /opt/solr-7.4.0/server/solr-webapp/webapp/ /usr/local/tomcat/webapps/
cd /usr/local/tomcat/webapps/
mv webapp/ solr

       (2) 把 solr-7.4.0\server\lib\ext 下的所有jar包 拷贝到 tomcat\webapps\solr 项目的WEB-INF\lib下

cd /opt/solr-7.4.0/server/lib/ext/
 
cp * /usr/local/tomcat/webapps/solr/WEB-INF/lib/

          把 solr-7.4.0\server\lib 目录下gmetric4j-1.0.7.jar和 lib目录下 metrics开头的jar包拷贝到 tomcat\webapps\solr 项目的WEB-INF\lib下

cd /opt/solr-7.4.0/server/lib

cp gmetric4j-1.0.7.jar metrics-* /usr/local/tomcat/webapps/solr/WEB-INF/lib/

       (3) 把 solr-7.4.0\server 下面的 solr 文件夹拷贝到  tomcat/webapps/solr 下面 ,并重命名为 solrhome (注意:不要放在中文目录下面)

cd /opt/solr-7.4.0/server/
 
cp -r solr /usr/local/tomcat/webapps/solr/solrhome

  (4)/usr/local/tomcat/webapps/solr/WEB-INF\web.xml,修改如下,找到以下代码 把注释去掉 然后把 /put/your/solr/home/here 改为你自己的solrhome的路径,我的路径是/usr/local/tomcat/webapps/solr/solrhome (这里改的是绝对地址)

<env-entry>
 
    <env-entry-name>solr/home</env-entry-name>
 
    <env-entry-value>/usr/local/tomcat/webapps/solr/solrhome</env-entry-value>
 
    <env-entry-type>java.lang.String</env-entry-type>
 
</env-entry>

      (5)把 solr-7.4.0\server\resources下的log4j2.xml 拷贝到 /usr/local/tomcat/webapps/solr/WEB-INF/classes , 没有classes文件夹的话就新建一个

    mkdir -p /usr/local/tomcat/webapps/solr/WEB-INF/classes
     
    cp /opt/solr-7.4.0/server/resources/log4j2.xml  /usr/local/tomcat/webapps/solr/WEB-INF/classes/

      (6)在 /usr/local/tomcat/webapps/solr/WEB-INF/web.xml  里面找到以下代码 ,将其注释

    <security-constraint>
     
      <web-resource-collection>
     
            <web-resource-name>Disable TRACE</web-resource-name>
     
           <url-pattern>/</url-pattern>
     
           <http-method>TRACE</http-method>
     
       </web-resource-collection>
     
     <auth-constraint/>
     
    </security-constraint>

到这里 就可以访问浏览器了 : http://127.0.0.1:8080/solr/index.html  

(把 127.0.0.1 换成你自己的服务器ip地址就可以了)

(注意:如果没有不能打开 有可能是端口被占用 或者 tomacat 没有启动)

二、配置Solr 索引数据库

       我们要用 Solr查 数据,首先要把我们数据库要用到的数据 先导入到 Solr 的库里,以下步骤就是 Solr 连接数据库的一些配置

1、建立 索引库

                     

    (1)以上操作后会在/usr/local/tomcat/webapps/solr/sorlhome/下面新建一个 new_core 的文件夹,查看在new_core下面有没有以下文件: 

                                   

如果没有 可以将solr-7.4.0/example/example-DIH/solr/db下的文件 拷贝到 /usr/local/tomcat/webapps/solr/sorlhome/new_core下

cp -r /opt/solr-7.4.0/example/example-DIH/solr/db/* /usr/local/tomcat/webapps/solr/sorlhome/new_core

然后在 new_core 文件夹下面新建一个 data 文件 用来放数据

     (2)导入数据还需要jar包

     ① 下载 mysql驱动包,放到/usr/local/tomcat/webapps/solr/WEB-INF/lib/ 目录下

 wget http://central.maven.org/maven2/mysql/mysql-connector-java/6.0.6/mysql-connector-java-6.0.6.jar

    ② 拷贝dist文件夹里的solr-dataimporthandler-7.2.0.jar

cp  /opt/solr-7.4.0/dist/solr-dataimporthandler-* /usr/local/tomcat/webapps/solr/WEB-INF/lib/

   ③ 拷贝lucene-libs文件夹里的中文分析器的jar包

cp  /opt/solr-7.4.0/contrib/analysis-extras/lucene-libs/* /usr/local/tomcat/webapps/solr/WEB-INF/lib/

   ④ 打开new_core下的conf目录在solrconfig.xml、db-data-config.xml、managed-schema中进行配置,

  

    首先solrconfig.xml,查看里面有没有以下代码,没有的话添加进去

<lib dir="../../../dist/" regex="solr-dataimporthandler-.*\.jar" />  
<lib dir="../../../dist/" regex="mysql-connector-java-.*\.jar" />
    <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
         <lst name="defaults">
                 <str name="config">data-config.xml</str>
         </lst>
    </requestHandler>

 然后 db-data-config.xml ,把数据库连接和需要导入的sql语句和字段配置好(我这边的数据是连表查询的数据,根据你自己的需要写sql语句)

<dataConfig>
    <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://106.15.228.67:3306/b2b_aoce" user="aoce" password="xy121228562!" />
        <document>
        <entity name="products"
              query="SELECT
                p.id,
                s.id as sid,
                p.`name`,
                p.`shop_id`,
                c1.`name` AS first_cat_name,
                c2.`name` AS second_cat_name,
                c3.`name` AS third_cat_name,
                b.`name` AS brand,
                b.`logo` AS brand_logo,
                s.price,
                s.sale_price,
                s.attributes,
                p.cover_image
              FROM
                products p,
                product_categories c1,
                product_categories c2,
                product_categories c3,
                product_brands b,
                product_skus s
              WHERE
                p.brand_id = b.id
                AND p.product_type=1
                AND s.product_id = p.id
                AND p.first_cat = c1.id
                AND p.second_cat = c2.id
                AND p.third_cat = c3.id
              ORDER BY
                p.id DESC">

              <field column='id' name='id' />
              <field column='sid' name='sid' />
              <field column='name' name='name' />
              <field column='shop_id' name='shop_id' />
              <field column='brand' name='brand' />
              <field column='brand_logo' name='brand_logo' />
              <field column='first_cat_name' name='first_cat_name' />
              <field column='second_cat_name' name='second_cat_name' />
              <field column='third_cat_name' name='third_cat_name' />
              <field column='price' name='price' />
              <field column='sale_price' name='sale_price' />
              <field column='attributes' name='attributes' />
              <field column='cover_image' name='cover_image' />
        </entity>
    </document>
</dataConfig>

最后 managed-schema 里面根据你要查询的字段配置以下,uniqueKey 的type类型必须要string,其它的可以根据你自己的字段设置,text_ik这个是我设置的中文分词类型 ,后面会讲

   <field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
   <field name="sid" type="pint" indexed="true" stored="true" multiValued="false" />
   <field name="shop_id" type="pint" indexed="true" stored="true" multiValued="false" />
   <field name="name" type="text_ik" indexed="true" stored="true"/>
   <field name="brand" type="string" indexed="true" stored="true"/>
   <field name="brand_logo" type="string" indexed="true" stored="true"/>
   <field name="cover_image" type="string" indexed="true" stored="true"/>
   <field name="first_cat_name" type="string" indexed="true" stored="true" multiValued="false"/>
   <field name="second_cat_name" type="string" indexed="true" stored="true" multiValued="false"/>
   <field name="third_cat_name" type="string" indexed="true" stored="true" multiValued="false"/>
   <field name="attributes" type="string" indexed="true" stored="true" multiValued="false"/>
   <field name="price"  type="pfloat" indexed="true" stored="true"/>
   <field name="sale_price"  type="pfloat" indexed="true" stored="true"/>
<uniqueKey>id</uniqueKey>

⑤ 下载ik分词器 并将jar包放在WEB-INF 的lib下

http://search.maven.org/remotecontent?filepath=com/github/magese/ik-analyzer-solr7/7.x/ik-analyzer-solr7-7.x.jar

然后编辑 new_core/conf/managed-schema 加入ik中文分词器

<fieldType name="text_ik" class="solr.TextField">
 
    <analyzer type="index">
 
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
 
        <filter class="solr.LowerCaseFilterFactory"/>
 
    </analyzer>
 
    <analyzer type="query">
    
        <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>
 
        <filter class="solr.LowerCaseFilterFactory"/>
 
    </analyzer>
 
</fieldType>

三、使用 Solr

1、php使用solr

(1)下载php的solr扩展 https://pecl.php.net/package/solr  选择最新版本

注意:php有Thread Safe和NoneThread Safe之分,下载之前,请先确定你安装的php是哪种类型。

                 

下载解压之后,将其中的dll文件放到php的扩展目录,对于php扩展所在目录,然后在php.ini开启solr扩展,再通phpinfo查看是否正常安装

2、在Laravel项目中使用Solr

(1)安装Laravel 的solr依赖

composr require solarium/solarium

执行完成后 ,在composer.json的"require" 中增加了一项

"solarium/solarium": "^4.0"

就成功了~

(2)搜索 ,注意 实例化的时候 要把 类先引入进来

/**
     * 首页全文搜索
     * @return \Illuminate\Support\Collection
     */
    public function searchProduct(Request $request){
        $data = $request->all();
        $key=$data['key'];//搜索传入的字段
        if(isset($data['page']) && !empty($data['page'])){//page是第几页
            if($data['page']==1){
                $start=0;
            }else{
                $start=($data['page']-1)*15;
            }
        }else{
            $start=0;
        }
        if(isset($data['order']) && !empty($data['order'])){//我这里的order是用于根据什么排序
            if($data['order']==4){
                $sort=['sale_price','asc'];
            }else{
                $sort=['id','asc'];
            }
        }else{
            $sort=['id','asc'];
        }

        if(isset($data['sale_price']) && !empty($data['sale_price'])){//筛选价格范围
           $price_start=$data['sale_price']['start'];
           $price_end=$data['sale_price']['end'];

        }else{
            $price_start='*';
            $price_end='*';
        }
        //solr数据库配置
        $options = [
            'endpoint' => [
                'localhost' => [
                   'host' => '127.0.0.1',  //IP地址
                   'port' => 8080,         //端口号
                   'core' => null,
                   'path' => '/solr/new_core',//solr 索引库位置
                   'wt'=>'json',
                ],
           ],
        ];

        $client = new Client($options);//实例化 solr类
        $query = $client->createSelect();//创建查询
        $query->setStart($start);//用于分页 从第几条取,初始0
        $query->setRows("15");//用于分页 每次取多少条
        $query->setQuery($key);// 筛选条件
        $query->createFilterQuery('sale_price')->setQuery('sale_price:['.$price_start.' TO '.$price_end.']');
//筛选价格范围

        if(isset($data['brand']) && !empty($data['brand'])) {
       $query->createFilterQuery('brandName')->setQuery('brandName:'.$data['brand']);
//筛选的品牌
        }
        if(isset($data['first_cat_name']) && !empty($data['first_cat_name'])) {//分类查询
$query->createFilterQuery('first_cat_name')->setQuery('first_cat_name:'.$data['first_cat_name']);//筛选产品分类
        }
        $query->addSort($sort[0],$sort[1]);//排序
        $query->setQueryDefaultField("name");//默认筛选 key 的字段名字,我这里是查产品名字
      

        $facetSet = $query->getFacetSet();// facet 开启,facet 是用于 查询符合筛选的全部产品的分组,比如我搜索了 “海康”,取了 第一页 15条数据,它会另外返回我一个 符合筛选条件的数据的全部品牌分组
        if(!isset($data['brand'])) {
            $facetSet->createFacetField('brand')->setField('brand');//facet 获得品牌分组
        }
        if(!isset($data['first_cat_name'])) {
            $facetSet->createFacetField('first_cat_name')->setField('first_cat_name');//facet获得分类分组
        }

        $resultset = $client->select($query);// 查询 执行
        if(!isset($data['brand'])) {
            $resultset->getFacetSet()->getFacet('brand');//facet 在select 执行前 set,在select执行后需要再 get 一下
        }
        if(!isset($data['first_cat_name'])) {
            $resultset->getFacetSet()->getFacet('first_cat_name');
        }

        $response= $resultset->getData();//取数据
        $response=(array)$response;

         return $this->success(ErrorConst::SUCCESS_CODE,$response);
     }

(3)新增 ,我这里就用写死的数据代替了

 /**
     * 首页全文搜索
     * 增加索引/更新索引(根据所传id是否已经存在,存在则更新,否则新增)
     * @return \Illuminate\Support\Collection
     */
    public function updateSearchProduct(Request $request) {

            $options = [
                'endpoint' => [
                    'localhost' => [
                       'host' => '127.0.0.1',  //IP地址
                       'port' => 8080,         //端口号
                       'core' => null,
                       'path' => '/solr/new_core',
                       'wt'=>'json',
                    ],
               ],
            ];
            $client =new Client($options);

            $data=array(
                "id"=>"15339",
                "sid"=>9867,
                "shop_id"=>41,
                "second_cat_name"=>"摄像机",
                "first_cat_name"=>"视频监控",
                "price"=>380.0,
                "name"=>"海康威视POE供电网络监控摄像头",
                "third_cat_name"=>"网络高清摄像机",
                "attributes"=>"3:机型,12:枪型;4:分辨率,27:500万像素;5:供电,33:DC12V;6:红外夜视,40:30米;9:外壳,98:铝合金",
                "cover_image"=>"http://xxxx.com/upload/image/19480/qp3z5ujfw2nxy4mtclhg1533605053.jpg",
                "brand"=>"海康威视",
            );

            $update=$client->createUpdate($data);
            $doc=$update->createDocument();
            foreach ($data as $key=>$value){
                    $doc->$key=$value;
                }
            $update->addDocument($doc);
            $update->addCommit();
            $updateResponse=$client->update($update);
            $res = $updateResponse->getResponse();
        return $this->success(ErrorConst::SUCCESS_CODE,$res->getStatusCode());
    }

(4)删除

    public function delete(Request $request) {
     
            $data = $request->json()->all();
     
            $id=$data['id'];
     
            //solr数据库配置
            $options = [
                'endpoint' => [
                    'localhost' => [
                       'host' => '127.0.0.1',  //IP地址
                       'port' => 8080,         //端口号
                       'core' => null,
                       'path' => '/solr/new_core',//solr 索引库位置
                       'wt'=>'json',
                    ],
               ],
            ];

            $client = new Client($options);//实例化 solr类
     
            $update = $client->createUpdate();
     
            $update->addDeleteById($id);//通过id
     
            //$update->addDeleteQuery($q);//通过查询条件
     
            $update->addCommit();
     
            $result = $client->update($update);
     
            $res = $result->getResponse();
     
            return $res->getStatusCode();
     
    }

 

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值