Solr搜索服务
【简介】
Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现。Apache Solr 中存储的资源是以 Document 为对象进行存储的。每个文档由一系列的 Field 构成,每个 Field 表示资源的一个属性。Solr 中的每个 Document 需要有能唯一标识其自身的属性,默认情况下这个属性的名字是 id,在 Schema 配置文件中使用:id进行描述。
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。Solr是一个独立的企业级搜索应用服务器,很多企业运用solr开源服务。原理大致是文档通过Http利用XML加到一个搜索集合中。查询该集合也是通过 http收到一个XML/JSON响应来实现。它的主要特性包括:高效、灵活的缓存功能,垂直搜索功能,高亮显示搜索结果,通过索引复制来提高可用性,提供一套强大Data Schema来定义字段,类型和设置文本分析,提供基于Web的管理界面等。
常用的搜索服务器:
- Lucence
- solr 全文搜索服务器 solrj客户端
- Elastic Search
一、solr的安装与配置
【安装】
解压solr-4.10.3.zip
-
把D:\Tomcat\solr\solr-4.10.3\example\webapps目录下的solr.war
部署到tomcat(tomcat要启动),然后删除solr.war文件(先关掉tomcat再删除)
(Tomcat最好用全新的来测试,当startup.bat执行后没部署war包,可先借用eclipse的Tomcat来部署一次) -
把D:\Tomcat\solr\solr-4.10.3\example\lib\ext 之下的.jar复制到
D:\Tomcat\solr\apache-tomcat-8.0.50\webapps\solr\WEB-INF\lib 之下 -
创建solrHome(相当于solr的工作目录), 存放solr服务器所有配置文件的目录。
把D:\Tomcat\solr\solr-4.10.3\example\solr(示例的工作目录) 复制到任意的solr文件夹并改名"solrHome" (位置任意吧,看你喜欢)
再把D:\Tomcat\solr\solr-4.10.3\之下的contrib和dist两个目录复制到solrHome文件夹中。
-
指定solr服务器的solrHome的位置
修改solr工程的web.xml文件:
<!--设置solr工程关联Tomcat服务器-->
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<!--在此处修改为之前创建的solr工程的路径-->
<env-entry-value>D:/Tomcat/solr/apache-tomcat-8.0.50/solr/solrHome</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
-
启动tomcat,访问http://localhost:8080/solr/
作用:主要做一些搜索数据的测试, 最终通过solj客户端来访问solr服务器
【配置业务字段】
1. 配置中文分词器,手动配置
FildType中指定
– IK Analyzer 的jar包添加到solr的web工程lib中
– 把IK Analyzer的扩展词典、停用词典、配置文件复制到solr的web工程的classes中(classes要自己创建)
D:\Tomcat\solr\apache-tomcat-8.0.50\webapps\solr\WEB-INF\classes
2.编写schema.xml
– 配置FieldType(分词器的字段类型)
位置:
solrHome/collection1/conf/schema.xml
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
solr中的业务字段先配置后使用
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="long" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category_name" type="string" indexed="true" stored="true" />
<field name="item_desc" type="text_ik" indexed="true" stored="true" />
<field name="item_goodsid" type="text_ik" indexed="true" stored="true" />
<field name="item_category" type="text_ik" indexed="true" stored="true" />
<field name="item_brand" type="text_ik" indexed="true" stored="true" />
<field name="item_seller" type="text_ik" indexed="true" stored="true" />
<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_sell_point" dest="item_keywords"/>
<copyField source="item_desc" dest="item_keywords"/>
配置好后,重启一下tomcat喔。
二、solr-demo
普通项目结构:
导包:
执行前需要先启动了solr并已经有导入了数据喔。
public class TestSolr {
@Test
public void testAdd() throws IOException, SolrServerException {
//创建solrj的连接
SolrServer solrServer=new HttpSolrServer("http://localhost:8080/solr");
//创建solr的文档document
SolrInputDocument document=new SolrInputDocument();
document.addField("id","item007");
document.addField("item_title","华为手机Meta30测试");
document.addField("item_price","3000");
document.addField("item_desc","5G手机");
solrServer.add(document);
solrServer.commit();
System.out.println("数据添加完成。");
}
@Test
public void testQuery() throws SolrServerException {
//创建solrj的连接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
SolrQuery query=new SolrQuery();
query.set("q","item_price:[3000 TO 5000]");
query.set("sort","item_price desc");
query.setStart(0);
query.setRows(100);
QueryResponse queryResponse=solrServer.query(query);
SolrDocumentList list = queryResponse.getResults();
System.out.println("list.getNumFound() = " + list.getNumFound());
for (SolrDocument document : list) {
System.out.println(document.get("id"));
System.out.println(document.get("item_title"));
System.out.println(document.get("item_price"));
System.out.println("-------------------------");
}
}
}
三、SpringBoot搭建
项目结构:
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>org.example</groupId>
<artifactId>springboot-solrj-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
<exclusions>
<exclusion>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--集成druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/pinyougoudb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: root
data:
solr:
host: http://127.0.0.1:8080/solr
AppSolrj.java
@SpringBootApplication
@MapperScan("com.online.shopping.mapper")
public class AppSolrj {
public static void main(String[] args) {
SpringApplication.run(AppSolrj.class,args);
}
}
TestSolrj.java
@SpringBootTest
public class TestSolrj {
@Autowired
private SolrTemplate solrTemplate;
@Autowired
private TbItemMapper tbItemMapper;
@Test
public void testRemoveAll(){
Query query=new SimpleQuery("*:*");
solrTemplate.delete("collection1",query);
solrTemplate.commit("collection1");
System.out.println("删除完成。");
}
@Test
public void testAdd(){
TbItem item=new TbItem();
item.setId(10L);
item.setTitle("荣耀手机");
item.setPrice(3000D);
item.setImage("http://localhost:9000/mall/xxx.jpg");
solrTemplate.saveBean("collection1",item);
solrTemplate.commit("collection1");
System.out.println("添加成功。");
}
@Test
public void importData(){
List<TbItem> list = tbItemMapper.selectByExample(null);
solrTemplate.saveBeans("collection1",list);
solrTemplate.commit("collection1");
System.out.println("添加成功。");
}
@Test
public void testQuery(){
Query query=new SimpleQuery("*:*");
//select * from xxx where item_title =?
Criteria criteria=new Criteria("item_title").endsWith("手机");
query.setRows(100);
query.addCriteria(criteria);
ScoredPage<TbItem> scoredPage = solrTemplate.query("collection1", query, TbItem.class);
List<TbItem> list = scoredPage.getContent();
for (TbItem item : list) {
System.out.println(item.getTitle()+","+item.getPrice()+","+item.getImage());
}
}
}
最后要记得 持久化对象 的属性和solr业务字段的映射关系,也就是在pojo的javabean要设置好映射。
schema.xml
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
TbItem .java
public class TbItem implements Serializable {
/**
* 商品id,同时也是商品编号
*
* @mbg.generated
*/
@Field
private Long id;
/**
* 商品标题
*
* @mbg.generated
*/
@Field("item_title")//表示 持久化对象 的属性和solr业务字段的映射关系
private String title
//其它省略
}