天天看点

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