1. 程式人生 > >solr服務快速搭建、配置中文分詞、資料匯入即solrj增刪改查

solr服務快速搭建、配置中文分詞、資料匯入即solrj增刪改查

一.準備工作

1. 環境準備:

1.1 centos 6.5/mac os 10.12.6

2. 假定一個需求:現在需要索引商品資訊,以支撐前臺商品展示頁面的搜尋。

  1. 資料庫中的表有商品分類表和商品詳情表
-- 商品表:
DROP TABLE IF EXISTS `rd_product`;
CREATE TABLE `rd_product` (
  `id` varchar(32) NOT NULL COMMENT '商品編號',
  `p_name` varchar(100) NOT NULL COMMENT '商品名稱',
  `p_price` decimal
(20,2) NOT NULL COMMENT '商品單價', `p_amount` int(10) NOT NULL COMMENT '商品數量', `p_desc` varchar(1000) DEFAULT NULL COMMENT '商品描述', `p_type` varchar(32) DEFAULT NULL COMMENT '商品型別', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--  商品型別表:
DROP TABLE IF EXISTS `rd_type`;
CREATE TABLE `rd_type`
( `id` varchar(32) NOT NULL COMMENT '型別編號', `t_name` varchar(100) NOT NULL COMMENT '型別名稱', `t_desc` varchar(1000) DEFAULT NULL COMMENT '型別詳情', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二. 搭建standalone模式(單機)的solr服務

1. 安裝並啟動服務。

​ 解壓solr-6.6.0.tgz壓縮包,在解壓後的資料夾下,使用自帶的jetty容器啟動solr服務,預設埠為8983,也可以自定義埠啟動。

預設啟動的命令:bin/solr start

指定埠啟動(8080)的命令:bin/solr start -p 8080

服務停止命令:bin/solr stop

2. 檢視管理介面。

​ 在瀏覽器中訪問http://localhost:8983/solr,進入solr的管理介面,

3. 建立索引庫。

​ 索引存放在索引庫中,此時solr中是沒有索引庫的,需要建立一個索引庫,並命名為RD-Core

建立索引庫的命令:bin/solr create -c RD-Core

刪除索引庫的命令:bin/solr delete -c RD-Core

4. 配置中文分詞器

如果不需要自定義敏感詞彙和行業名詞,可以使用solr自帶的分詞器,否則需要使用IK-Analyzerpaoding等分詞器。

4.1 配置solr自帶的分詞器(選擇性配置,也可以都配置上)

4.1.1 引入分詞器的jar檔案:在server/solr/RD-Product/conf/solrconfig.xml中配置如下資訊。

<!-- 引入"contrib/rd-lib/"下所有jar檔案 -->
<lib dir="${solr.install.dir:../../../..}/contrib/analysis-extras/lucene-libs/" regex=".*\.jar" />

4.1.2 新增一箇中文分詞的欄位型別(filedType):在solr中,欄位型別(fieldType)相當於資料庫中的欄位型別(intvarchar…),在server/solr/RD-Product/conf/managed-schema中配置如下內容

<fieldType name="text_smartcn" class="solr.TextField" positionIncrementGap="0">
    <!-- 索引時的分詞器 -->
    <analyzer type="index">
      <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
    </analyzer>
    <!-- 查詢時的分詞器 -->
    <analyzer type="query">
       <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/>
    </analyzer>
</fieldType>

4.2 配置IKAnalyzer分詞器

4.2.1 新增分詞器的jar檔案:在contrib下新建資料夾rd-lib,並將ik-analyzer-solr6.x.jar拷貝進來,這個資料夾用來存放第三方jar檔案,後面做資料匯入時候,用到的mysql資料庫驅動也放到這個資料夾下。

4.2.2 引入分詞器的jar檔案:在server/solr/RD-Product/conf/solrconfig.xml中配置如下資訊,將rd-lib這個資料夾下的所有jar包引入到服務中。

<!-- 引入"contrib/rd-lib/"下所有jar檔案 -->
<lib dir="${solr.install.dir:../../../..}/contrib/rd-lib/" regex=".*\.jar" />

4.2.3 新增一箇中文分詞的欄位型別(filedType):在server/solr/RD-Product/conf/managed-schema中配置如下內容

<!--中文分詞器IK Analyzer-->
<fieldType name="text_ik" class="solr.TextField">
  <!--索引時候的分詞器-->
  <analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
  <!--查詢時候的分詞器-->
  <analyzer type="query">
    <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" isMaxWordLength="false" useSmart="false"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

4.2.4 自定義敏感詞彙與行業專屬詞彙(如果不需要,可以跳過)

server/solr-webapp/webapp/WEB-INF/下新建一個資料夾classes,並新建檔案IKAnalyzer.cfg.xml,內容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
    <comment>IK Analyzer 擴充套件配置</comment>
    <!--使用者可以在這裡配置自己的擴充套件字典,'/'表示專案的根路徑,多個檔案用';'分隔 -->
    <entry key="ext_dict">/ext1.txt;/ext2.txt;</entry> 
    <!--使用者可以在這裡配置自己的擴充套件停止詞字典-->
    <!-- <entry key="ext_stopwords">stopwords.txt;</entry>  --> 
</properties>

5. 新增需要索引的欄位

​ 我們需要索引商品的名稱、價格、數量、商品描述、商品型別和商品型別描述,則在檔案server/solr/RD-Product/conf/managed-schema中配置如下欄位,其中的name是自定義的,不需要與資料庫保持一致,type可以是solr內建的資料型別,也可以是上面配置的中文分析器的型別,如果欄位包含中文,強烈建議配置為text_smartcntext_ik

<!-- 商品資訊 -->
<field name="p_name" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>
<field name="p_price" type="float" indexed="true" stored="true" multiValued="true"/>
<field name="p_amount" type="int" indexed="true" stored="true" multiValued="true"/>
<field name="p_desc" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>
<field name="p_type_name" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="t_desc" type="text_smartcn" indexed="true" stored="true" multiValued="true"/>

6. 配置資料庫連線(如果不需要從資料庫匯入資料,該步驟可以省略)

6.1 引入資料匯入的jar包,並新增資料匯入處理器,在server/solr/RD-Product/conf/solrconfig.xml中配置

<!-- 匯入資料夾dist下所有的jar -->
<lib dir="${solr.install.dir:../../../..}/dist/" regex=".*\.jar" />

<!--資料庫匯入索引的配置檔案 -->
   <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
    <lst name="defaults">
      <str name="config">data-config.xml</str>
     </lst>
  </requestHandler> 

6.2 在server/solr/RD-Product/conf/中建立data-config.xml,並在其中配置資料庫與索引庫的連線資訊。

<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
  <!-- 資料庫驅動及資料庫資訊,資料庫:rd_mall,使用者名稱:root,密碼為空 -->
  <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/rd_mall" user="root" password="" batchSize="-1" />
  <document>
    <entity name="rd_product" query="SELECT p.id AS 'pID',p.p_name AS 'pName',p.p_price AS 'pPrice',p.p_amount AS 'pAmount',p.p_desc AS 'pDesc',t.t_name AS 'pType',t.t_desc AS 't_desc' FROM rd_product p,rd_type t WHERE p.p_type=t.id">
      <!--column的id是資料庫的id,name的id是managed_schema裡面的id,id是必須,並且唯一的-->
      <field column="pID" name="id" />
      <!--column的pName是資料庫的p_name欄位,name的p_name是schema-managed中的欄位,下面配置同理-->
       <field name="p_name" column="pName"/>
        <field name="p_price" column="pPrice"/>
        <field name="p_amount" column="pAmount"/>
        <field name="p_desc" column="pDesc"/>
        <field name="p_type_name" column="pType"/>
        <field name="t_desc" column="tDesc"/>
    </entity>
  </document>
</dataConfig>

6.3 重啟服務後,使用以下命令匯入資料,至此,單機版的solr服務搭建完畢。

重啟服務:bin/solr restart

匯入資料:curl http://localhost:8983/solr/RD-Product/dataimport\?command\=full-import

刪除所有資料:bin/post -c RD-Product -d "<delete><query>*:*</query></delete>"

刪除指定id的資料:bin/post -c RD-Product -d "<delete><id>p001</id></delete>"

二. SolrJ的使用示例

1.新建一個maven專案,pom.xml如下配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sgcc.gdt.search</groupId>
    <artifactId>rd_solr_demo</artifactId>
    <version>1.0.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-solr</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.增(改)、刪、查及資料庫匯入資料的使用

public class SearchServer {
    /** solr服務客戶端 */
    private SolrClient solrClient;
    /** solr服務的地址 */
    private String solrURL = "http://127.0.0.1:8983/solr";
    /** solr索引庫的名稱 */
    private String coreName = "RD-Product";

    /**
     * 獲取solr服務的客戶端
     */
    @Before
    public void init() {
        solrClient = new HttpSolrClient("http://127.0.0.1:8983/solr");
    }

    /**
     * 關閉solr服務
     */
    @After
    public void destroy() throws IOException {
        if (solrClient != null) {
            solrClient.close();
        }
    }

    /**
     * 查詢示例
     */
    @Test
    public void queryTest() throws IOException, SolrServerException {
        //查詢條件
        SolrQuery solrQuery = new SolrQuery();
        solrQuery.setQuery("*:*");
        //查詢方法
        QueryResponse response = solrClient.query(coreName, solrQuery);
        SolrDocumentList results = response.getResults();
        System.out.println("查詢結果:" + response);
    }

    /**
     * 新增索引
     */
    @Test
    public void add() throws IOException, SolrServerException {
        //構造索引文件
        SolrInputDocument document = new SolrInputDocument();
        String id = UUID.randomUUID().toString().replaceAll("-", "");
        document.setField("id", id);
        document.setField("p_name", "神州膝上型電腦");
        document.setField("p_price", 1234f);
        document.setField("p_amount", 100);
        document.setField("p_type_name", "電腦");

        //新增索引文件
        solrClient.add(coreName, document);
        solrClient.commit(coreName);
        System.out.println("新增成功!");
    }

    /**
     * 刪除索引
     */
    @Test
    public void delete() throws IOException, SolrServerException {
        solrClient.deleteByQuery(coreName, "*:*");
        System.out.println("刪除成功!");
    }

    /**
     * 從資料庫匯入索引
     */
    @Test
    public void dataImportTest() throws IOException {
        String path1 = "http://localhost:8983/solr/RD-Product/dataimport?command=full-import";
        RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
        HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
        HttpGet httpGet = new HttpGet(path1);
        HttpResponse response = httpClient.execute(httpGet);
        int statusCode = response.getStatusLine().getStatusCode();
        if(statusCode == HttpStatus.SC_OK){
            httpGet.abort();
            System.out.println("匯入資料成功!");
        }
    }
}