注意:需要提前配置好linux下的java环境
文章目录
前言
这篇文章会记录我再学习solr时出现的一些问题
提示:以下是本篇文章正文内容,下面案例可供参考
一、solr简介?
大多数搜索引擎应用都必须具有某种搜索功能,问题是搜索功能往往是巨大的资源消耗并且它们由于沉重的数据库加载而拖垮你的应用的性能。
这就是为什么转移负载到一个外部的搜索服务器是一个不错的主意,Apache Solr是一个流行的开源搜索服务器,它通过使用类似REST(一种软件架构风格,表述性状态传递)的HTTP API,这就确保你能从几乎任何编程语言来使用solr。
Solr是一个开源搜索平台,用于构建搜索应用程序。 它建立在Lucene(全文搜索引擎)之上。?Solr是企业级的,快速的和高度可扩展的。 使用Solr构建的应用程序非常复杂,可提供高性能。
为了在CNET(ZOL,PCHOME,蜂鸟网)网络的公司网站上添加搜索功能,Yonik Seely于2004年创建了Solr。并在2006年1月,它成为Apache软件基金会下的一个开源项目。并于2016年发布最新版本Solr 6.0,支持并行SQL查询的执行。
Solr可以和Hadoop一起使用。由于Hadoop处理大量数据,Solr帮助我们从这么大的源中找到所需的信息。不仅限于搜索,Solr也可以用于存储目的。像其他NoSQL数据库一样,它是一种非关系数据存储和处理技术。
总之,Solr是一个可扩展的,可部署,搜索/存储引擎,优化搜索大量以文本为中心的数据。
二、solr在linux上的安装步骤
-
首先将准备好的压缩包放入linux,(我的是放在:
/usr/local/src/
)
使用tar -xvf solr-4.10.3.tgz
解压 -
把 solr 下的dist目录solr-4.10.3.war部署到 Tomcat\webapps下(去掉版本号)
cd /usr/local/src/solr-4.10.3/dist/
cp solr-4.10.3.war /usr/local/tomcat/webapps/solr.war
-
启动 Tomcat解压缩 war 包
cd /usr/local/tomcat/bin
./startup.sh
-
把solr下example/lib/ext 目录下的所有的 jar 包,添加到 solr 的工程中(\WEB-INF\lib目录下)。
cp /root/solr-4.10.3/example/lib/ext/*.jar /usr/local/tomcat/webapps/solr/WEB-INF/lib/
-
创建一个 solrhome(/usr/local/solrhome) 。solr 下的/example/solr 目录就是一个 solrhome。复制此目录到/usr/local改名为solrhome
cp /root/solr-4.10.3/example/solr /usr/local/ -r
cd /usr/local
mv solr solrhome
-
关联 solr 及 solrhome。需要修改 solr 工程的 web.xml 文件。
vi /usr/local/tomcat/webapps/solr/WEB-INF/web.xml
然后将下面的value修改为你自己的目录
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-value>/usr/local/solrhome</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>
- 最后重启一下tomcat,通过http://IP:8080/solr/能访问到solr的主页就可以了
接下来我们要对solr的域进行配置(在完成上述步骤之后)
- 修改solrhome的schema.xml 文件 设置业务系统 Field,这里要与你的实体类中的字段进行关联
<field name="item_goodsid" type="long" indexed="true" stored="true"/>
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="double" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category" type="string" indexed="true" stored="true" />
<field name="item_seller" type="text_ik" indexed="true" stored="true" />
<field name="item_brand" type="string" indexed="true" stored="true" />
<field name="item_updatetime" type="pdate" indexed="true" stored="true" />
- 复制域:复制域的作用在于将某一个Field中的数据复制到另一个域中
<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_category" dest="item_keywords"/>
<copyField source="item_seller" dest="item_keywords"/>
<copyField source="item_brand" dest="item_keywords"/>
- 还有最后一个动态域:当我们需要动态扩充字段时,我们需要使用动态域。而动态域的配置直接在schema.xml后加如下代码即可
<dynamicField name="item_spec_*" type="string" indexed="true" stored="true" />
到这里solr已经可以正常使用了,但是在使用英文进行搜索的情况下,中文的语义较为复杂,一句话中的词可以分为多个意思,而我们在使用搜索的时候通常都是关键字搜索,因此在使用中文进行搜索的时候有很多的不便,因此我们需要在配置一个分词器
三、IK Analyzer的的简介
IK Analyzer 是一个开源的,基亍 java 语言开发的轻量级的中文分词工具包。从 2006年 12 月推出 1.0 版开始, IKAnalyzer 已经推出了 4 个大版本。最初,它是以开源项目Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。从 3.0 版本开始,IK 发展为面向 Java 的公用分词组件,独立亍 Lucene 项目,同时提供了对 Lucene 的默认优化实现。在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化。
四、IK Analyzer的安装
- 将IK的安装包放入linux的
/usr/local/src/
目录下面,使用unzip IK Analyzer 2012FF_hf1.zip
解压目录如图
- 把IKAnalyzer2012FF_u1.jar 添加到 solr 工程(
/usr/local/tomcat/webapps/solr/WEB-INF
)的 lib 目录下 - 创建WEB-INF/classes文件夹 把扩展词典、停用词词典、配置文件放到 solr 工程的 WEB-INF/classes 目录下。
ext_stoword.dic
IKAnalyzer.cfg.xml
mydict.dic
- 修改 Solrhome(
/usr/local/solrhome/collection1/conf
) 的 schema.xml 文件,配置一个 FieldType,使用 IKAnalyzer
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
- /text_ik 搜索出位置,展示即即可
现在我们已经在将solr整个配置好了,那我们要如何在项目中使用solr呢?接下来我们一起来用一下solr
五.对solr的使用
- 首先我们需要新建一个maven项目,加入solr所需的依赖
在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.offcn</groupId>
<artifactId>spring-data-solr-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring-data-solr-demo</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<spring.version>4.2.4.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- 引入Jedis和SpringDataRedis依赖 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>1.5.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
- 在
applicationContext-solr.xml
中对solr进行配置
记得将IP修改为你自己的地址不然是用不了的
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:solr="http://www.springframework.org/schema/data/solr"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<solr:solr-server id="solrServer" url="http://192.168.88.143:8080/solr"/>
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg ref="solrServer"/>
</bean>
</beans>
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
- 编写所需的实体类,solr依赖实体类进行操作
其中@Field默认为主键 而下面的与之间配置的域一一对应 没写的不会在solr中进行显示
public class TbItem implements Serializable {
@Field
private Long id;
@Field("item_title")
private String title;
private String sellPoint;
@Field("item_price")
private BigDecimal price;
private Integer stockCount;
private Integer num;
private String barcode;
@Field("item_image")
private String image;
private Long categoryid;
private String status;
private Date createTime;
@Field("item_updatetime")
private Date updateTime;
private String itemSn;
private BigDecimal costPirce;
private BigDecimal marketPrice;
private String isDefault;
@Field("item_goodsid")
private Long goodsId;
private String sellerId;
private String cartThumbnail;
@Field("item_category")
private String category;
@Field("item_brand")
private String brand;
private String spec;
@Field("item_seller")
private String seller;
}
- 对solr进行测试
其中solrTemplate
是操作solr的核心对象 另外需要注意的是在对solr进行增删改的时候都需要进行commit操作
package com.offcn;
import com.offcn.pojo.TbItem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleFacetQuery;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* Hello world!
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-solr.xml")
public class App {
@Autowired
SolrTemplate solrTemplate;
@Test
public void setValue() {
TbItem item = new TbItem();
item.setId(1L);
item.setGoodsId(10L);
item.setTitle("华为 P40 pro 手机");
item.setPrice(new BigDecimal(2000));
item.setCategory("手机");
item.setSellerId("dongyimai");
item.setBrand("华为");
solrTemplate.saveBean(item);
solrTemplate.commit();
}
@Test
public void getValue() {
TbItem item = solrTemplate.getById("1", TbItem.class);
System.out.println(item.getTitle() + "..." + item.getPrice());
}
/**
* 根据主键删除商品
*/
@Test
public void deleteItem() {
solrTemplate.deleteById("1");
solrTemplate.commit();
}
@Test
public void addItemList() {
List<TbItem> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
TbItem item = new TbItem();
item.setId(i + 1L);
item.setGoodsId(10L);
item.setTitle("华为 P40 pro 手机 " + i);
item.setPrice(new BigDecimal(2000 + i));
item.setCategory("手机");
item.setSellerId("dongyimai");
item.setBrand("华为");
list.add(item);
}
solrTemplate.saveBeans(list);
solrTemplate.commit();
}
/**
* 分页查询
*/
@Test
public void queryByPage(){
Query query = new SimpleQuery("*:*");
query.setOffset(20);//设置开始查询得下标
query.setRows(20);//设置显示的行数
ScoredPage<TbItem> page = solrTemplate.queryForPage(query,TbItem.class);
List<TbItem> list = page.getContent();
showList(list);
}
/**
* 带条件的分页查询
*/
@Test
public void queryByCriteria(){
Query query = new SimpleQuery("*:*");
Criteria criteria = new Criteria("item_title");
criteria.contains("2");//查找出item_title中包含5的数据
query.addCriteria(criteria);//将条件添加到查询中
ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
System.out.println(page.getTotalElements());//获取总条数
List<TbItem> list = page.getContent();
showList(list);
//结论:分页查询,如果设置初始下标和显示行数,默认初始下标为0,显示行数为10
}
public void showList(List<TbItem> list){
for (TbItem tbItem : list) {
System.out.println(tbItem.getTitle()+"..." + tbItem.getPrice());
}
}
/**
* 删除solr库中所有的数据
*/
@Test
public void deleteAll(){
//*:*表示索引库中所有的数据
Query query = new SimpleQuery("*:*");
solrTemplate.delete(query);
}
}
solrTemplate操作solr的方法
solrTemplate.saveBean(Object o)
保存一个对象solrTemplate.saveBeans(List list)
保存一个集合solrTemplate.getById("id",Object.class)
通过主键id进行查询solrTemplate.deleteById("id")
根据id进行删除solrTemplate.commit()
提交数据到solr服务器solrTemplate.queryForPage(query,Object.class)
分页查询方法
solrTemplate操作solr的分页步骤
- 不带条件的分页查询
public void queryByPage(){
Query query = new SimpleQuery("*:*");
query.setOffset(20);//设置开始查询得下标
query.setRows(20);//设置显示的行数
ScoredPage<TbItem> page = solrTemplate.queryForPage(query,Object.class);
List<Object> list = page.getContent();
for (Object object: list) {
System.out.println(object);
}
}
- 带条件的分页查询
@Test
public void queryByCriteria(){
Query query = new SimpleQuery("*:*");
Criteria criteria = new Criteria("item_title");
criteria.contains("2");//查找出item_title中包含5的数据
query.addCriteria(criteria);//将条件添加到查询中
ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
System.out.println(page.getTotalElements());//获取总条数
List<TbItem> list = page.getContent();
//结论:分页查询,如果设置初始下标和显示行数,默认初始下标为0,显示行数为10
}
- 删除solr中所有的数据
/**
* 删除solr库中所有的数据
*/
@Test
public void deleteAll(){
//*:*表示索引库中所有的数据
Query query = new SimpleQuery("*:*");
solrTemplate.delete(query);
}