1. 程式人生 > >Spring整合Solr 7.4以上版本

Spring整合Solr 7.4以上版本

背景

之前專案中用到了Solr搜尋引擎,作為Java程式設計師,難免要用SolrJ來操作我們的Solr伺服器,實現索引的增刪改查。

當時公司用的SolrJ版本較老,今天重新看專案原始碼的時候,在pom.xml更新了jar包版本,發現有一些方法被標註過時,甚至已經被取代(在API中已經不存在了)。

訪問Solr官網釋出的最新API才明白,SolrJ API發生了一些微妙的變化,雖然這些變化不大,主要就是連線Solr伺服器的時候有點區別,但是如果不弄清楚的話,恐怕以後用到的時候報錯,心裡就該跑過一萬隻草泥馬了……

廢話說了這麼多,下面直接上程式碼!

在Spring配置檔案宣告Bean

需要注意,新版本的SolrJ API,不再使用HttpSolrServer來建立與Solr伺服器的連線,而是HttpSolrClient!!!

API推薦的建立連線的方法:

通過在HttpSolrClient的建構函式傳入一個其內部類Builder進行構建,需指定一個baseUrl。

具體大家可以看原始碼,此處就不貼出來了。

因為一般都用IoC容器管理我們的元件,所以這裡我們把它宣告在Spring配置檔案中。當然,你也可以專門寫一個管理類來負責建立、關閉連線、提交等等,只要保證在實際應用中前端傳過來請求之後,可以正確執行到相關程式碼就好。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
">
    <!--配置Solr-->
    <bean id="builder" class="org.apache.solr.client.solrj.impl.HttpSolrClient.Builder">

    </bean>
    <bean id="solr" class="org.apache.solr.client.solrj.impl.HttpSolrClient">
        <constructor-arg name="builder" value="builder" />
        <property name="baseURL" value="http://localhost:8083/solr/demo_core" />
    </bean>
</beans>

後臺程式碼

執行以下程式碼的前提是,你本地的Solr伺服器上有一個demo_core工程(當然這個是靈活的,隨便),而且工程裡搭配了IK中文分詞器,並且配置了索引庫欄位(不懂的可以查閱網上的資料,也可參考我的第一篇博文)。

package com.wang.money.utils;


import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;


public class SolrUtil {

    private static HttpSolrClient client;

    /**
     *  由於沒有Web環境,所以這裡手動載入IoC容器
     * */
    static {
        ApplicationContext context=new ClassPathXmlApplicationContext("application-context.xml");
        client=(HttpSolrClient) context.getBean("solr");
    }

    /**
     *  新增或更新文件
     * */
    @Test
    public void save() throws IOException, SolrServerException {
        SolrInputDocument document=new SolrInputDocument();  //注意是SolrInputDocument,而非SolrDocument
        //可為文件指定id,即addField("id","文件id"),如果id相同則操作為更新。
        document.addField("id","123");
        document.addField("appName","誰是機械狗");
        document.addField("appAPK","com.xxx.xxx");
        document.addField("appId",66);

        UpdateResponse responseAdd=client.add(document);  //這裡也不一樣,不像以往版本的提交
        client.commit();  //提交
        System.out.println("save一篇文件成功");
    }


    /**
     *  查詢文件
     * */
    @Test
    public void query() throws IOException, SolrServerException {
        //宣告查詢物件,並設定查詢條件
        SolrQuery query=new SolrQuery();
        query.set("q","appName:有沒有什麼關於機械的玩意");

        //執行查詢
        QueryResponse response=client.query(query);

        //獲取查詢結果,文件集
        SolrDocumentList documentList=response.getResults();
        for (SolrDocument document:documentList){
            System.out.println("查詢到的APP名稱:"+document.get("appName"));
            System.out.println("文件的ID:"+document.get("id"));
            System.out.println();
        }
    }


    /**
     *  刪除文件
     * */
    @Test
    public void delete() throws IOException, SolrServerException {
        client.deleteByQuery("appName:刪除所有關於機械的文件記錄");  //這是根據查詢條件刪除,也可根據id刪除
        client.commit();
        System.out.println("刪除成功");
    }
}

接下來開始執行就好,首先插入一條資料,即執行save()方法,然後執行查詢,因為我配置了IK中文分詞器,並且在appName欄位上指定了索引生成規則,所以我的查詢條件可以匹配出所有包含“機械”關鍵字的記錄,當然這裡只有兩條(我後來又添加了一條),你可以自己多save幾條進行測試。

 然後你再執行刪除方法,appName中包含“機械”兩個字的文件又都會被刪除,再次查詢就查不到了。