一:solr是什么?有什么用?
网上一大堆官方解释,刚学习的时候,看了还是不太明白。说通俗一点,它就是一个搜索引擎,用来查询数据的,就像在数据库查询一样。那为什么不直接使用数据库呢,大家知道,数据库在性能方面有很大瓶颈,而solr因为索引功能比数据库强大很多,性能比数据库高出很多,所以当我们需要大量的,复杂的查询时候,可以考虑使用solr。
二:solr的下载安装
下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/
下载得到zip压缩包,下载的版本为4.10.2. 文件大小148MB左右。
安装:
1、 将solr-4.10.2.zip文件拷贝到C盘;(或者其他盘都可以,只要目录中不要出现中文就行。)
2、 解压solr-4.10.2.zip文件,得到solr-4.10.2目录。
3、 运行è cmd 执行命(进入C:\solr-4.10.2\example):
4、 执行命令:java -jar start.jar
5、 打开浏览器,输入地址:http://localhost:8983/solr/
出现以下界面及安装成功
这时候solr当中还没有数据,我们导入它提供的先看看(实际应用中需要我们自己导入数据库的数据):
dos中进入到exampledocs:cd C:\solr-4.10.2\example\exampledocs
再输入命令:java -jar post.jar solr.xml monitor.xml
如下,可以查询到数据了:
A、搭建 taotao core
在实际的项目中,我们需要创建自己项目的solr core,在安装好的solr中有一个example,我们可以借助这个来创建自己的core(这里借助淘淘商城项目来举例)。
1、 在example目录下创建taotao-solr文件夹;
2、 将./solr下的solr.xml拷贝到taotao-solr目录下;
3、 在taotao-solr下创建taotao目录,并且在taotao目录下创建conf和data目录;
4、 将example\solr\collection1\core.properties文件拷贝到example\taotao-solr\taotao下,并且修改name=taotao;
5、 将example\solr\collection1\conf下的schema.xml、solrconfig.xml拷贝到example\taotao-solr\taotao\conf下;
6、 修改schema.xml文件,保留以下三种标签,使其配置最小化:
解释:<field>中,name对应数据库表的字段(带'_'为保留字段,如"_version_","_root_"),type是数据类型,需要在<fieldType>中指定,indexed表示该字段是否需要建立索引(如果查询的时候作为查询条件,则需要),stored表示查询后该字段的值是否需要存储(如果有用,比如前台需要,就存储)。multiValued表示是否有多个值。<uniqueKey>标签表示唯一键。
7、 修改solrconfig.xml文件,修改一些配置,大部分配置先保持默认:
a) 将所有的<lib>标签注释掉;
b) 搜索<str name="df">text</str>替换成<str name="df">title</str>
表示搜索时,如果没有指定字段,就走该字段。
c) 将<searchComponent name="elevator" class="solr.QueryElevationComponent" >注释掉(这个的功能类似百度的竞价排名):
8、 启动solr: 进入solr的example目录下
java -Dsolr.solr.home=taotao-solr -jar start.jar
到此,taotao core就创建好了,但是上面的title字段会有中文,所以我们需要增加中文分词器。
下载IK中文分词器jar包 IKAnalyzer-2012-4x.jar,拷贝到以下目录:
然后在schema.xml文件的<fieldType>中指定该类型,具体看上面name="text_ik"的配置
B、把数据库数据导入到solr中
搭建好core后,我们需要把数据库表中的数据导入到solr中,然后查询的时候就可以从solr中查,在导入之前,先看一下使用solrj完成索引数据的增删改查
1、导入solrj包
2、代码
public class ItemDataTest {
private HttpSolrServer httpSolrServer;
@Before
public void setUp() throws Exception {
// 在url中指定core名称:taotao
//http://solr.taotao.com/#/taotao -- 界面地址
String url = "http://solr.taotao.com/taotao"; //服务地址
HttpSolrServer httpSolrServer = new HttpSolrServer(url); //定义solr的server
httpSolrServer.setParser(new XMLResponseParser()); // 设置响应解析器
httpSolrServer.setMaxRetries(1); // 设置重试次数,推荐设置为1
httpSolrServer.setConnectionTimeout(500); // 建立连接的最长时间
this.httpSolrServer = httpSolrServer;
}
@Test
public void testInsert() throws Exception{
Item item = new Item();
item.setCid(1L);
item.setId(999L);
item.setImage("image");
item.setPrice(100L);
item.setSellPoint("很好啊,赶紧来买吧.");
item.setStatus(1);
item.setTitle("飞利浦 老人手机 (X2560) 深情蓝 移动联通2G手机 双卡双待");
this.httpSolrServer.addBean(item);
this.httpSolrServer.commit();
}
@Test
public void testUpdate() throws Exception{
Item item = new Item();
item.setCid(1L);
item.setId(999L);
item.setImage("image");
item.setPrice(100L);
item.setSellPoint("很好啊,赶紧来买吧. 豪啊");
item.setStatus(1);
item.setTitle("飞利浦 老人手机 (X2560) 深情蓝 移动联通2G手机 双卡双待");
this.httpSolrServer.addBean(item);
this.httpSolrServer.commit();
}
@Test
public void testDelete() throws Exception{
this.httpSolrServer.deleteById("999");
this.httpSolrServer.commit();
}
@Test
public void testQuery() throws Exception{
int page = 2;
int rows = 1;
String keywords = "手机";
SolrQuery solrQuery = new SolrQuery(); //构造搜索条件
solrQuery.setQuery("title:" + keywords); //搜索关键词
// 设置分页 start=0就是从0开始,,rows=5当前返回5条记录,第二页就是变化start这个值为5就可以了。
solrQuery.setStart((Math.max(page, 1) - 1) * rows);
solrQuery.setRows(rows);
//是否需要高亮
boolean isHighlighting = !StringUtils.equals("*", keywords) && StringUtils.isNotEmpty(keywords);
if (isHighlighting) {
// 设置高亮
solrQuery.setHighlight(true); // 开启高亮组件
solrQuery.addHighlightField("title");// 高亮字段
solrQuery.setHighlightSimplePre("<em>");// 标记,高亮关键字前缀
solrQuery.setHighlightSimplePost("</em>");// 后缀
}
// 执行查询
QueryResponse queryResponse = this.httpSolrServer.query(solrQuery);
List<Item> items = queryResponse.getBeans(Item.class);
if (isHighlighting) {
// 将高亮的标题数据写回到数据对象中
Map<String, Map<String, List<String>>> map = queryResponse.getHighlighting();
for (Map.Entry<String, Map<String, List<String>>> highlighting : map.entrySet()) {
for (Item item : items) {
if (!highlighting.getKey().equals(item.getId().toString())) {
continue;
}
item.setTitle(StringUtils.join(highlighting.getValue().get("title"), ""));
break;
}
}
}
for (Item item : items) {
System.out.println(item);
}
}
}
有了上面的代码,我们要导入数据到solr中,就可以在该类中添加以下代码:
通过后台系统从数据库查询数据库的数据,使用一个do while循环。其中,Item是对应schema.xml文件中的配置建立的,如下:
导入之后,就可以使用了,下面整合spring来实现查询:
配置文件:
在service中注入HttpSolrServer,就可以查询了
public SearchResult searchItem(String keyWords, int page, int rows) {
SolrQuery solrQuery = new SolrQuery(); // 构造搜索条件
solrQuery.setQuery("title:" + keyWords + " AND status:1"); // 搜索关键词
// 设置分页 start=0就是从0开始,,rows=5当前返回5条记录,第二页就是变化start这个值为5就可以了。
solrQuery.setStart((Math.max(page, 1) - 1) * rows);
solrQuery.setRows(rows);
// 是否需要高亮
boolean isHighlighting = !StringUtils.equals("*", keyWords) && StringUtils.isNotEmpty(keyWords);
if (isHighlighting) {
// 设置高亮
solrQuery.setHighlight(true); // 开启高亮组件
solrQuery.addHighlightField("title");// 高亮字段
solrQuery.setHighlightSimplePre("<em>");// 标记,高亮关键字前缀
solrQuery.setHighlightSimplePost("</em>");// 后缀
}
try {
// 执行查询
QueryResponse queryResponse = this.httpSolrServer.query(solrQuery);
List<Item> items = queryResponse.getBeans(Item.class);
if (isHighlighting) {
// 将高亮的标题数据写回到数据对象中
Map<String, Map<String, List<String>>> map = queryResponse.getHighlighting();
for (Map.Entry<String, Map<String, List<String>>> highlighting : map.entrySet()) {
for (Item item : items) {
if (!highlighting.getKey().equals(item.getId().toString())) {
continue;
}
item.setTitle(StringUtils.join(highlighting.getValue().get("title"), ""));
break;
}
}
}
return new SearchResult(queryResponse.getResults().getNumFound(), items);
} catch (SolrServerException e) {
e.printStackTrace();
}
return null;
}
以上就是solr的大概使用方法,,当数据库的数据在变化时,我们必须保证solr中数据的同步。