天天看點

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

一、Solr概述

Solr 是Apache下的一個頂級開源項目,采用Java開發,它是基于Lucene的全文搜尋服務。Solr自帶伺服器功能,可以通過指令方式直接啟動solr服務。也可以把solr部署到Jetty、Tomcat等其他Servlet容器中運作。

  • Solr與lucene的關系

Lucene是一個開放源代碼的全文檢索引擎工具包,它不是一個完整的全文檢索應用。Lucene僅提供了完整的查詢引擎和索引引擎,目的是為軟體開發人員提供一個簡單易用的工具包,以友善的在目标系統中實作全文檢索的功能,或者以Lucene為基礎建構全文檢索應用。Solr的目标是打造一款企業級的搜尋引擎系統,它是基于Lucene一個搜尋引擎服務,可以獨立運作,通過Solr可以非常快速的建構企業的搜尋引擎,通過Solr也可以高效的完成站内搜尋功能。

二、Solv安裝配置

2.1 下載下傳Solr

下載下傳位址:http://archive.apache.org/dist/lucene/solr/

如果是Windows版本,那麼下載下傳完成後直接解壓縮到指定目錄即可。目錄結果如下圖所示:

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

bin:solr的運作腳本;

contrib:solr相關的第三方擴充jar包;

dist:該目錄包含build過程中産生的war和jar檔案,以及相關的依賴檔案;

docs:api文檔;

example:solr工程的示例;

licenses:各種許可和協定;

server:solr自帶的伺服器目錄。其中有兩個比較重要的目錄:

    |- solr:運作Solr的配置檔案都儲存在這裡。其中,它包含一個子檔案夾configsets,該檔案夾存放了solr的示例配置檔案

    |- solr-webapp:solr背景管理系統所在目錄

2.2 啟動自帶solr服務

第一步:在指令行進入solr/bin目錄,然後執行solr start指令即可。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

solr服務預設監聽8983端口。啟動成功後,在浏覽器上輸入localhost:8983/solr即可打開solr管理界面。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

2.3 建立solr core

一個solr core就是一個索引庫。一個solr伺服器上可以有多個solr core。

第一步:進入%solr_home%/server/solr目錄,建立一個目錄,該目錄作為一個索引庫目錄存放我們建立的索引。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

第二步:将%solr_home%\server\solr\configsets\sample_techproducts_configs目錄下的conf檔案夾拷貝到solrtest目錄中。

第三步:重新開機solr服務。

solr restart -p 8983
           

例如:

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

啟動成功後,重新通路solr管理界面。

第四步:點選左邊Core Admin菜單,然後點選Add Core,在name和InstanceDir輸入框中輸入solr core檔案夾的名稱,輸入完後點選藍色的Add Core按鈕。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

這時候在左邊core selector中可以看到我們建立的solr core。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

2.4 管理界面介紹

(1)DashBoard

儀表盤,顯示了該Solr執行個體開始啟動運作的時間、版本、系統資源、jvm等資訊。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

(2)Logging

Solr運作日志資訊。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

(3)Core Admin

Solr Core管理界面,在這裡可以添加SolrCore執行個體。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

(4)Java Properties

Solr在JVM 運作環境中的屬性資訊,包括類路徑、檔案編碼、jvm記憶體設定等資訊。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

(5)Thread Dump

顯示Solr Server中目前活躍線程資訊,同時也可以跟蹤線程運作棧資訊。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

(6)Core Selector

選擇一個SolrCore進行詳細操作。具體操作如下所示:

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

其中有幾個比較常用的功能:

Analysis:通過此界面可以測試索引分析器和搜尋分析器的執行情況。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

Dataimport:定義資料導入處理器,可以從關系資料庫将資料導入到Solr索引庫中。預設沒有配置,需要手工配置;

Documents:通過/update表示更新索引,solr預設根據id(唯一限制)域來更新Document的内容,如果根據id值搜尋不到id域則會執行添加操作,如果找到則更新;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

Query:通過/select執行搜尋索引,必須指定“q”查詢條件方可搜尋。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

q: 查詢關鍵字;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

fq: (filter query)過濾查詢,在q查詢結果中再把符合fq的内容篩選出來;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

sort:排序,desc代表降序,asc代表升序;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

start: 分頁顯示使用,開始記錄下标,從0開始;

rows:指定傳回結果最多有多少條記錄,配合start來實作分頁;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

fl: (Field List)指定傳回那些字段内容,用逗号或空格分隔多個;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

df:(Default Field)指定預設搜尋Field;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

wt: (writer type)指定輸出格式,可以有xml、json等格式;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

hl: 是否高亮 ,設定高亮Field,設定格式字首和字尾;

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

三、Solrj的使用

3.1 什麼是solrj

solrj是通路Solr服務的java用戶端,提供索引和搜尋的請求方法。

lucene&solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

3.2 環境搭建

搭建Maven工程,并引入solrj相關坐标;

<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>8.2.0</version>
</dependency>
           

3.3 添加或修改索引

public class CreateIndexTest {
	// 設定solr服務接口
	String baseURL = "http://127.0.0.1:8983/solr/solrtest";
	
	SolrClient solrClient;
	
	@Before
	public void init() {
		// 建立SolrServer對象
		solrClient = new HttpSolrClient.Builder(baseURL).build();
	}

	// 添加和更新索引
	@Test
	public void testCreateIndex() throws Exception {
		// 建立SolrInputDocument對象
		SolrInputDocument document = new SolrInputDocument();
		
		// 添加Field
		document.addField("id", "103");
		document.addField("content_ik", "中華人民共和國");

		// 把SolrInputDocument對象添加到索引庫中
		solrClient.add(document);

		// 送出
		solrClient.commit();
	}
	
}
           

上面solrClient.add(document)方法會根據id域來更新Document的内容,如果根據id值搜尋不到id域則會執行添加操作。

3.4 删除索引

// 根據條件删除
solrClient.deleteByQuery("*:*");

// 送出
solrClient.commit();
           

*注意:*:代表删除所有索引,需要慎用。

3.5 查詢索引

@Test
public void testSearchIndex() throws Exception {
	// 建立搜尋對象
	SolrQuery query = new SolrQuery();
	
	// 設定搜尋條件
	query.setQuery("*:*");
	
	// 發起搜尋請求
	QueryResponse response = solrClient.query(query);
	
	// 處理搜尋結果
	SolrDocumentList results = response.getResults();
	System.out.println("搜尋到的結果總數:" + results.getNumFound());
	
	// 周遊搜尋結果
	for (SolrDocument solrDocument : results) {
		System.out.println("----------------------------------------------------");
		System.out.println("id:" + solrDocument.get("id"));
		System.out.println("content" + solrDocument.get("content"));
	}
}
           

3.6 複雜查詢

@Test
public void testSearchIndex2() throws Exception {
	// 建立搜尋對象
	SolrQuery solrQuery = new SolrQuery();
	// 設定查詢條件
	solrQuery.setQuery("搜尋引擎");

	// 設定過濾條件
	solrQuery.setFilterQueries("bookName:lucene", "bookPrice:[49 TO 99]");

	// 設定排序
	solrQuery.setSort("bookPrice", ORDER.desc);

	// 設定分頁
	solrQuery.setStart(0);
	solrQuery.setRows(10);

	// 設定顯示Field域
	solrQuery.setFields("id, bookName, bookPrice, bookPic, bookRemark");

	// 設定預設搜尋Field域
	solrQuery.set("df", "bookName");

	// 設定高亮
	solrQuery.setHighlight(true);
	solrQuery.addHighlightField("bookName");
	solrQuery.setHighlightSimplePre("<font color=\"red\">");
	solrQuery.setHighlightSimplePost("</font>");

	// 查詢資料
	QueryResponse response = solrClient.query(solrQuery);
	
	// 擷取查詢結果的記錄數
	SolrDocumentList results = response.getResults();
	System.out.println("搜尋到的資料總條數:" + results.getNumFound());

	Map<String, Map<String, List<String>>> map = response.getHighlighting();

	// 解析查詢結果
	for (SolrDocument solrDocument : results) {
		System.out.println("----------------------------------------------------");
		// 顯示高亮
		List<String> list = map.get(solrDocument.get("id")).get("bookName");
		System.out.println("編号:" + solrDocument.get("id"));
		if (list != null && list.size() > 0) {
			System.out.println("書名:" + list.get(0));
		} else {
			System.out.println("書名:" + solrDocument.get("bookName"));
		}
		System.out.println("價格:" + solrDocument.get("bookPrice"));
		System.out.println("圖檔:" + solrDocument.get("bookPic"));
		System.out.println("描述:" + solrDocument.get("bookRemark"));
	}
}
           

四、配置中文分詞器

第一步:下載下傳ikanalyzer。

下載下傳位址:https://mvnrepository.com/artifact/com.jianggujin/IKAnalyzer-lucene/8.0.0

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

第二步:把下載下傳好的jar包複制到%solr_home%\server\solr-webapp\webapp\WEB-INF\lib目錄下。

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

第三步:把下面三個檔案複制到%solr_home%\server\solr-webapp\webapp\WEB-INF\classes目錄下。這三個檔案可以從ikanalyzer.jar檔案中獲得。

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

第四步:修改%solr_home%\server\solr\solrtest\conf\managed-schema檔案,配置中文分詞器。

<!-- ik分詞器 -->
<fieldType name="text_ik" class="solr.TextField">
	<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
	
<field name="content_ik" type="text_ik" indexed="true" stored="true" />
           

修改完成後重新開機solr服務,進入analysis頁面,在Field Value中輸入要分詞的内容,然後再選擇FieldType為content_ik,最後點選藍色按鈕即可。效果如下圖所示:

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

下面沒有使用ikanalyzer分詞器的效果(供大家參考):

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

五、導入資料

需求:使用solr背景導入資料庫中book表的資料到solr中。

功能分析:

1.需要在solr的schema.xml檔案定義要存儲的商品Field。

2.需要把MySQL的資料導入到solr索引庫中

3.開發搜尋功能

5.1 引入jar包

複制%solr_home%/dist目錄下的solr-dataimporthandler包到%solr_home%/contrib/dataimporthandler/lib目錄下。

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

準備mysql驅動包,然後添加到%solr_home%\contrib\db\lib目錄下。如果沒有lib目錄,則自己建立。

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

修改%solr_home%\server\solr\solrtest\conf目錄下的sqlrconfig.xml檔案。修改内容如下:

<lib dir="${solr.install.dir:../..}/contrib/dataimporthandler/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:../..}/contrib/db/lib" regex=".*\.jar" />
           

5.2 配置資料源

在%solr_home%\server\solr\solrtest\conf目錄下建立data-config.xml檔案,該檔案配置了Document中每個Field與資料庫表的對應關系。配置如下:

<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
    <!-- 資料庫資訊 -->
    <dataSource type="JdbcDataSource" 
        driver="com.mysql.jdbc.Driver" 
        url="jdbc:mysql://localhost:3306/solr" 
        user="root" password="root"/>
    <document>
        <!-- document實體 -->
        <entity name="book" query="SELECT * FROM book">
            <!-- 資料庫字段映射solr字段 -->
            <field column="id" name="id"/>
            <field column="name" name="bookName"/>
            <field column="price" name="bookPrice"/>
            <field column="pic" name="bookPic"/>
            <field column="remark" name="bookRemark"/>
        </entity>
    </document>
</dataConfig>
           

修改%solr_home%\server\solr\solrtest\conf目錄下的sqlrconfig.xml檔案:

<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
	<lst name="defaults">
		<str name="config">data-config.xml</str>
	</lst>
</requestHandler>
           

5.3 配置Field

修改%solr_home%\server\solr\solrtest\conf目錄下的managed-schema檔案,在最後面加入下面内容:

<field name="bookName" type="text_ik" indexed="true" stored="true" />
<field name="bookPrice" type="pint" indexed="true" stored="true"  />
<field name="bookPic" type="string" indexed="false" stored="true"  />
<field name="bookRemark" type="text_ik" indexed="true" stored="false" />	
<field name="book_keywords" type="text_ik" indexed="true" stored="true" multiValued="true"/>
<copyField source="bookName" dest="book_keywords"/>
<copyField source="bookRemark" dest="book_keywords"/>
           

copyField:将多個Field複制到一個Field中,以便進行統一的檢索。當建立索引時,solr伺服器會自動的将source域的内容複制到dest目标域中。如果指定dest目标域為預設搜尋域,可以提高查詢效率。

配置完成後,重新開機solr服務。

5.4 背景導入操作

點選Dataimport菜單,選擇Entity,然後點選Execute按鈕執行導入。導入成功後界面如下所示:

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

在Overview中可以看到索引庫的資訊。

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr

六、SpringBoot整合solr

第一步:建立springboot項目,引入相關坐标。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.16.18</version>
</dependency>
           

第二步:建立實體類。

package solrjtest.beans;

import lombok.Data;

@Data
public class Book {
	private Integer id;
	private String name;
	private Integer price;
	private String pic;
	private String remark;
}
           

第三步:建立Service接口,該接口定義一個方法,用于從solr中查詢索引,并傳回結果。

public interface IBookService {

	List<Book> searchBook() throws Exception;
	
}
           

第四步:建立Service實作類。

package solrjtest.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import solrjtest.beans.Book;
import solrjtest.service.IBookService;

@Service
public class BookServiceImpl implements IBookService {
	
	@Autowired
	private SolrClient solrClient;

	@Override
	public List<Book> searchBook() throws Exception {		
		// 建立搜尋對象
		SolrQuery solrQuery = new SolrQuery();
		// 設定查詢條件
		solrQuery.setQuery("搜尋引擎");

		// 設定過濾條件
		solrQuery.setFilterQueries("bookName:lucene", "bookPrice:[49 TO 99]");

		// 設定排序
		solrQuery.setSort("bookPrice", ORDER.desc);

		// 設定分頁
		solrQuery.setStart(0);
		solrQuery.setRows(10);

		// 設定顯示Field域
		solrQuery.setFields("id, bookName, bookPrice, bookPic, bookRemark");

		// 設定預設搜尋Field域
		solrQuery.set("df", "bookName");

		// 設定高亮
		solrQuery.setHighlight(true);
		solrQuery.addHighlightField("bookName");
		solrQuery.setHighlightSimplePre("<font color=\"red\">");
		solrQuery.setHighlightSimplePost("</font>");

		// 查詢資料
		QueryResponse response = solrClient.query(solrQuery);
		
		// 擷取查詢結果的記錄數
		SolrDocumentList results = response.getResults();
		System.out.println("搜尋到的資料總條數:" + results.getNumFound());

		Map<String, Map<String, List<String>>> map = response.getHighlighting();

		List<Book> books = new ArrayList<Book>();
		
		// 解析查詢結果
		for (SolrDocument solrDocument : results) {
			// 顯示高亮
			List<String> list = map.get(solrDocument.get("id")).get("bookName");
			// 擷取Field的值
			String id = (String) solrDocument.get("id");
			String bookName = "";
			if (list != null && list.size() > 0) {
				bookName = list.get(0);
			} else {
				bookName = (String) solrDocument.get("bookName");
			}
			int bookPrice = (int) solrDocument.get("bookPrice");
			String bookPic = (String) solrDocument.get("bookPic");
			String bookRemark = (String) solrDocument.get("bookRemark");
			
			// 把擷取到Field的值封裝成Book對象
			Book book = new Book();
			book.setId(Integer.parseInt(id));
			book.setName(bookName);
			book.setPrice(bookPrice);
			book.setPic(bookPic);
			book.setRemark(bookRemark);
			books.add(book);
		}

		return books;
	}

}
           

第五步:建立控制器。

@Controller
@RequestMapping("/book")
public class BookController {
	
	@Autowired
	private IBookService bookService;

	@RequestMapping(path="/list", produces={"application/json;charset=utf-8"})
	@ResponseBody
	public List<Book> list() {
		try {
			return bookService.searchBook();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
}
           

第六步:配置solr。

spring:
  data:
    solr:
      host: http://192.168.31.20:8983/solr/solrtest
           

第七步:建立啟動類。

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}
           

最終在浏覽器上看到的效果如下圖所示:

lucene&amp;solr入門(二)一、Solr概述二、Solv安裝配置三、Solrj的使用四、配置中文分詞器五、導入資料六、SpringBoot整合solr