天天看點

Solr 09 - SolrJ操作Solr單機服務 (Solr的Java API)

本篇基于Solr 4.10.4的單機服務, 介紹了SolrJ的使用方法, 包括fq分組查詢、hl高亮顯示等.

目錄

  • 1 SolrJ是什麼
  • 2 SolrJ對索引的CRUD操作
    • 2.1 建立Maven工程(打包方式選擇為jar)
    • 2.2 配置pom.xml檔案, 加入SolrJ的依賴
    • 2.3 添加和修改索引
    • 2.4 删除索引
    • 2.5 查詢索引
  • 3 SolrJ的查詢方案
    • 3.1 實作步驟
    • 3.2 示例代碼
    • 3.3 代碼搜尋結果
    • 3.4 檢視分片統計資料
    • 3.5 分片統計資料結果
  • 版權聲明

說明: SolrJ是通路Solr服務的Java用戶端程式, 提供了索引和搜尋的請求方法.

SolrJ通常嵌入在業務系統中, 通過SolrJ的API接口操作Solr服務, 流程如下圖:

Solr 09 - SolrJ操作Solr單機服務 (Solr的Java API)

使用SolrJ通路Solr服務, 完成索引的增、删、改、查操作.

Solr 09 - SolrJ操作Solr單機服務 (Solr的Java API)

<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>

    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- solrj版本 -->
        <solrj.version>4.10.4</solrj.version>
        <!-- log4j日志版本 -->
        <slf4j.version>1.7.7</slf4j.version>
        <log4j.version>1.2.17</log4j.version>
        <!-- jcl版本 -->
        <jcl.version>1.7.6</jcl.version>
        <junit.version>4.12</junit.version>
    </properties>

    <dependencies>
        <!-- solrj依賴 -->
        <dependency>
            <groupId>org.apache.solr</groupId>
            <artifactId>solr-solrj</artifactId>
            <version>${solrj.version}</version>
        </dependency>
        <!-- log4j日志包 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${jcl.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>${jcl.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
</project>
           

說明: Solr是根據id域(唯一限制)執行索引的添加(或更新)的:

先根據id域執行查詢, 查詢到執行更新; 查詢不到則執行添加.

步驟:

(1) 建立HttpSolrServer對象, 連接配接Solr服務;

(2) 建立文檔對象(SolrInuptDocument);

(3) 使用HttpSolrServer對象, 執行添加(或更新);

(4) 送出.

/**
 * 添加與修改索引
 */
@Test
public void testSaveAndUpdateIndex() throws Exception {
    // 1. 建立HttpSolrServer對象, 連接配接Solr服務
    // 參數baseURL: 指定Solr的服務位址
    HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
    
    // 2. 建立文檔對象(SolrInputDocument)
    SolrInputDocument document = new SolrInputDocument();
    // 在Solr中, id域是必需的
    document.addField("id", "9527");
    // 先設定如下值: 
    // document.addField("name", "solr solrj");
    // 再次設定, 測試更新索引 -- 如果存在則更新, 不存在則添加
    document.addField("name", "solr123 solrj");
    
    // 3. 使用HttpSolrServer對象, 執行添加(或更新)
    server.add(document);
    // 4. 送出更新
    server.commit();
}
           
Solr 09 - SolrJ操作Solr單機服務 (Solr的Java API)

(1) 根據id删除索引, 步驟為:

① 建立HttpSolrServer對象, 連接配接Solr服務;

② 使用HttpSolrServer對象, 執行删除;

③ 送出.

/**
 * 根據id删除索引
 */
@Test
public void testDeleteIndexById() throws SolrServerException, IOException {
    // 1. 建立HttpSolrServer對象, 連接配接Solr服務
    // 參數baseURL: 指定Solr的服務位址
    HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
    
    // 2. 使用HttpSolrServer對象, 執行删除
    server.deleteById("9527");
    
    // 3. 送出
    server.commit();
}
           

(2) 根據條件删除索引, 步驟為:

① 建立HttpSolrServer對象, 連接配接solr服務;
/**
 * 根據條件删除索引
 */
@Test
public void testDeleteIndexByQuery() throws Exception {
    // 1. 建立HttpSolrServer對象, 連接配接Solr服務
    HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
    
    // 2. 使用HttpSolrServer對象, 執行删除
    server.deleteByQuery("name: solr");
    
    // 3. 送出更新
    server.commit();
}
           

查詢步驟:

(1) 建立HttpSolrServer對象, 連接配接Solr服務;

(2) 建立查詢對象(SolrQuery);

(3) 使用HttpSolrServer對象, 執行查詢, 傳回查詢響應對象QueryResponse;

(4) 使用QueryResponse對象, 擷取查詢的結果集SolrDocumentList;

(5) 處理結果集.

/**
 * 查詢索引
 */
@Test
public void testQueryIndex() throws Exception {
    // 1. 建立HttpSolrServer對象, 連接配接Solr服務
    HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
    
    // 2. 建立查詢對象(Query)
    // : 表示查詢所有
    SolrQuery query = new SolrQuery(":");
    
    // 3.使用HttpSolrServer對象, 執行查詢, 傳回查詢響應對象QueryResponse
    QueryResponse queryResponse = server.query(query);
    
    // 4.使用QueryResponse對象, 擷取查詢的結果集SolrDocumentList
    SolrDocumentList results = queryResponse.getResults();
    
    // 5.處理結果集
    // 列印查詢到的結果數量
    System.out.println("結果數量: " + results.getNumFound());
    for (SolrDocument doc : results) {
        System.out.println("= = = = = = = = = = = = = = = = = = =");
        // 列印id域和name域
        System.out.println("id: " + doc.get("id"));
        System.out.println("name: " + doc.get("name"));
    }
}
           
Solr 09 - SolrJ操作Solr單機服務 (Solr的Java API)

(2) 建立查詢對象(SolrQuery), 設定查詢條件;

(3) 使用HttpSolrServer對象, 執行查詢, 傳回查詢響應對象(QueryResponse);

(4) 使用QueryResponse對象, 擷取查詢資料;

(5) 處理結果集.

/**
 * SolrJ進階查詢
 */
@Test
public void queryIndexSenior() throws Exception {
    // 1. 建立HttpSolrServer對象, 連接配接Solr服務
    // 參數baseURL:指定Solr的服務位址
    HttpSolrServer solrServer = new HttpSolrServer("http://127.0.0.1:7070/solr/collection1");
    
    // 2. 建立查詢對象(SolrQuery), 設定查詢條件
    SolrQuery solrQuery = new SolrQuery();
    // 2.1 設定查詢表達式
    solrQuery.setQuery("花兒朵朵");
    // 2.2 設定過濾條件
    solrQuery.setFilterQueries("product_price:[* TO 20]");
    // 2.3 設定排序sort
    solrQuery.setSort("product_price", ORDER.desc);
    // 2.4 設定分頁: start, rows
    solrQuery.setStart(0);
    solrQuery.setRows(10);
    // 2.5 設定顯示的域清單
    solrQuery.setFields("id", "product_name", "product_price", "product_catalog_name");
    // 2.6 設定預設的搜尋域
    solrQuery.set("df", "product_name");
    // 2.7 設定響應格式
    solrQuery.set("wt", "json");
    
    // 2.8 設定高亮顯示
    solrQuery.setHighlight(true);  // 開啟高亮顯示
    // 或者: solrQuery.setParam("hl", "true");
    solrQuery.addHighlightField("product_name");  // 添加高亮顯示的域
    solrQuery.setHighlightSimplePre("<font color='red'>");  // 設定高亮顯示的HTML标簽的字首
    solrQuery.setHighlightSimplePost("<font>");  // 設定高亮顯示的HTML标簽的字尾
    
    // 2.9 設定分片統計facet
    solrQuery.setFacet(true);  // 開啟分片統計
    solrQuery.addFacetField("product_catalog_name");  // 添加分片統計的域
    
    // 3. 使用HttpSolrServer對象, 執行查詢, 傳回查詢相應對象
    QueryResponse queryResponse = solrServer.query(solrQuery);
    
    /* 處理結果集
    NamedList list = (NamedList) queryResponse.getResponse().get("highlighting");
    for (int i = 0; i < list.size(); i++) {
        System.out.println("id=" + list.getName(i) + "高亮字段: " + list.getVal(i));
    }
    */
    
    // 4. 使用QueryResponse對象, 擷取查詢資料
    // 4.1 擷取查詢結果集
    SolrDocumentList results = queryResponse.getResults();
    // 4.2 擷取高亮顯示資料
    // 第一個Map的key是文檔的id, 第二個Map的key是高亮顯示的字段名, 第二個Map中的value是處理過的高亮顯示結果集, 類型為List<String>
    Map<String, Map<String, List<String>>> hlMap = queryResponse.getHighlighting();
    // 4.3 擷取分片統計資料
    List<FacetField> facetFields = queryResponse.getFacetFields();
    
    // 6. 處理結果集
    System.out.println("結果數量:" + results.getNumFound());
    for (SolrDocument doc : results) {
        System.out.println("= = = = = = = = = = = = = = = = = = =");
        // id, product_name, product_price, product_catalog_name
        // 擷取商品id
        String pid = doc.get("id").toString();
        // 擷取商品名稱: 先從高亮顯示結果中擷取, 若沒有擷取到, 再從doc中擷取
        String pname = "";
        List<String> list = hlMap.get(pid).get("product_name");
        if (null != list && list.size() > 0) {
            pname = list.get(0);
        } else {
            pname = doc.get("product_name").toString();
        }
        
        // 擷取商品價格
        String pprice = doc.get("product_price").toString();
        // 擷取商品的分類名稱
        String pcatalogName = doc.get("product_catalog_name").toString();
        
        // 輸出結果
        System.out.println("商品id: " + pid);
        System.out.println("商品名稱: " + pname);
        System.out.println("商品價格: " + pprice);
        System.out.println("商品分類名稱: " + pcatalogName);
    }
}
           

Solr 09 - SolrJ操作Solr單機服務 (Solr的Java API)

// 5. 處理分片統計資料(如有)
System.out.println("分片統計資料 = = = = = = = = = = = Begin");
for (FacetField field : facetFields) {
    System.out.println("統計域名稱: " + field.getName() + " , 統計到的組數量: " + field.getValueCount());
    // 檢視各個組的數量
    List<Count> values = field.getValues();
    for (Count count : values) {
        System.out.println("組名稱: " + count.getName() + " , 該組的數量: " + count.getCount());
    }
}
System.out.println("分片統計資料 = = = = = = = = = = = End");
           

Solr 09 - SolrJ操作Solr單機服務 (Solr的Java API)

作者: 馬瘦風

出處: 部落格園 馬瘦風的部落格

您的支援是對部落客的極大鼓勵, 感謝您的閱讀.

本文版權歸部落客所有, 歡迎轉載, 但請保留此段聲明, 并在文章頁面明顯位置給出原文連結, 否則部落客保留追究相關人員法律責任的權利.

繼續閱讀