Java接收solr动态域_Solr和Spring Data Solr

一.Solr概述与安装

1.Solr简介

Solr是一个开源搜索平台,用于构建搜索应用程序。 它建立在Lucene(全文搜索引擎)之上。 Solr是企业级的,快速的和高度可扩展的。Solr可以和Hadoop(http://www.yiibai.com/hadoop/)一起使用。由于Hadoop处理大量数据,Solr帮助我们从这么大的源中找到所需的信息。不仅限于搜索,Solr也可以用于存储目的。像其他NoSQL数据库一样,它是一种非关系数据存储和处理技术。总之,Solr是一个可扩展的,可部署,搜索/存储引擎,优化搜索大量以文本为中心的数据。

2.Linux下Solr的安装

1:把Tomcat安装包导入Linux系统,解压 Tomcat并重命名tomcat-solr

2:导入solr的Linux安装包到Linux服务器,解压 solr-4.10.3.tgz.tgz。

命令:tar -zxvf solr-4.10.3.tgz.tgz

3:把 solr 下的example/webapps/solr.war部署到 Tomcat-solr\webapps下(去掉版本号)。

命令:cp solr-4.10.3/example/webapps/solr.war tomcat-solr/webapps/

4:使用命令解压:unzip -oq solr.war -d solr

5:把solr下example/lib/ext 目录下的所有的 jar 包,添加到 solr 的工程中(\WEB-INF\lib目录下)。

命令:cp solr-4.10.3/example/lib/ext/* tomcat-solr/webapps/solr/WEB-INF/lib/

6:创建一个索引仓库。solr 下的/example/solr目录就是一个索引仓库。复制此目录【solr】到任意磁盘即可完成自定义索引仓库创建。

命令:cp -r solr-4.10.3/example/solr . (把solr索引库仓库文件夹拷贝当前目录; . 表示当前目录)

7:关联tomcat服务器中 solr项目 和 索引仓库solr。修改Tomcat/bin/catalina.sh文件指定索引仓库路径即可

//在Tomcat/bin/catalina.sh第二行指定索引仓库路径即可

export JAVA_OPTS="-Dsolr.solr.home=/usr/local/dintalk/singleSolr/solr"

8:启动 Tomcat

http://IP:8080/solr/

9.加载contrib,dist依赖类库

把solr-4.10.3/contrib,dist 文件夹拷贝 索引仓库目录下(和索引库在同一级目录)

命令:cp -r solr-4.10.3/contrib/ solr-4.10.3/dist/ solr

配置solr索引库中核心配置文件:solrConfig.xml 加载contrib,dist依赖jar包

Java接收solr动态域_Solr和Spring Data Solr_第1张图片

3.中文分析器IK Analyzer的安装

IK Analyzer 是一个开源的,基亍 java 语言开发的轻量级的中文分词工具包。最初,它是以开源项目Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。从 3.0 版本开始,IK 发展为面向 Java 的公用分词组件,独立亍 Lucene 项目,同时提供了对 Lucene 的默认优化实现。在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化。

3.1IK Analyzer配置

1、把IKAnalyzer2012FF_u1.jar 添加到 solr 工程的 lib 目录下

2、创建WEB-INF/classes(手动创建)文件夹 把扩展词典、停用词词典、配置文件放到 solr 工程的 WEB-INF/classes 目录下:

Java接收solr动态域_Solr和Spring Data Solr_第2张图片

3、修改 索引库 的 schema.xml 文件,配置一个 FieldType,使用 IKAnalyzer

4.业务域配置

域相当于数据库的表字段,用户存放数据,因此用户根据业务需要去定义相关的Field(域),一般来说,每一种对应着一种数据,用户对同一种数据进行相同的操作。

域的常用属性:

name:指定域的名称

type:指定域的类型

indexed:是否索引

stored:是否存储

required:是否必须

multiValued:是否多值

4.1普通域

修改solrhome的schema.xml 文件  设置业务系统 Field :

4.2复制域

复制域的作用在于将某一个Field中的数据复制到另一个域中 :

4.3动态域

当我们需要动态扩充字段时,我们需要使用动态域。所以我们需要使用动态域来实现。需要实现的效果示例如下 :

Java接收solr动态域_Solr和Spring Data Solr_第3张图片

二.Spring Data Solr

​如何将Solr的应用集成到Spring中?Spring Data Solr就是为了方便Solr的开发所研制的一个框架,其底层是对SolrJ(官方API)的封装。

1.Spring Data Solr 使用步骤

第一步:导入相关坐标

org.springframework.data

spring-data-solr

1.5.5.RELEASE

第二步:resources下编写配置文件(applicationContext-solr.xml)

http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">

第三步:为操作的实体类添加@Filed注解

public class TbItem implementsSerializable{//id 和solr中的主键名称一致可以不用写

@FieldprivateLong id;

@Field("item_title")privateString title;

@Field("item_image")privateString image;

...

第四步:基本的CRUD

/*** 测试Solr的简单操作

*@authorMr.song

* @date 2019/06/13 16:55*/@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration("classpath:applicationContext-solr.xml")public classSolrTest {

@AutowiredprivateSolrTemplate solrTemplate;

@Test//增加item

public voidtestAddItemToSolrHome(){

TbItem item= newTbItem();

item.setId(1L);

item.setTitle("测试Title");

item.setImage("这是图片");

solrTemplate.saveBean(item);//增删改需要提交

solrTemplate.commit();

}//重新赋值便是更新

@Test//根据主键查询

public voidtestQueryById(){

TbItem item= solrTemplate.getById(1L, TbItem.class);

System.out.println(item.getTitle());

}

@Test//条件查询

public voidtestQuery(){//查询所有, *:* 前面是字段 后面是条件

SimpleQuery simpleQuery = new SimpleQuery("*:*");//设置分页

simpleQuery.setOffset(5);//开始索引

simpleQuery.setRows(5);//每页记录数//拼接条件

Criteria criteria = new Criteria("item_title");

criteria= criteria.contains("苹果");

simpleQuery.addCriteria(criteria);

ScoredPage items = solrTemplate.queryForPage(simpleQuery, TbItem.class);for(TbItem item : items) {

System.out.println(item.getTitle());

}

}

@Test//删除item(根据主键删除)

public voidtestDelItem(){

solrTemplate.deleteById("1");

solrTemplate.commit();

}

@Test//清空

public voiddelSolrHome(){

SimpleQuery query= new SimpleQuery("*:*");

solrTemplate.delete(query);

solrTemplate.commit();

}

}

三.SpringDataSolr的常用API示例

/***@authorMr.song

* @date 2019/06/13 18:22*/@Servicepublic class ItemSearchServiceImpl implementsItemSearchService {

@AutowiredprivateTbItemMapper itemMapper;

@AutowiredprivateSolrTemplate solrTemplate;/*** 根据关键字查询solr索引库

*@paramsearchMap 前端的查询条件,封装为Map

*@return查询的结果,不封装为实体,返回Map效果一样*/@OverridepublicMap search(Map searchMap) {//1.关键字查询

String keywords = searchMap.get("keywords").toString();//2.封装查询条件(高亮查询)

SimpleHighlightQuery simpleHighlightQuery = newSimpleHighlightQuery();if (keywords != null) {//这是查询的域

Criteria criteria = new Criteria("item_keywords");

criteria=criteria.contains(keywords);

simpleHighlightQuery.addCriteria(criteria);

}//1.高亮查询的高亮设置(即查询关键字的高亮显示)

HighlightOptions options = newHighlightOptions();//设置高亮的头部和尾部

options.setSimplePrefix("");

options.setSimplePostfix("");//设置高亮的域名字,设置查询的选项

options.addField("item_title");

simpleHighlightQuery.setHighlightOptions(options);//2.过滤查询条件=====分类相关

String categoryStr = (String) searchMap.get("category");if (categoryStr != null){//2.1按照传入的分类字符串进行查询,创建过滤查询对象

SimpleFilterQuery filterQuery = newSimpleFilterQuery();//2.2创建条件,设置域的名称

Criteria criteria = new Criteria("item_category");//2.3设置匹配字符串

criteria =criteria.contains(categoryStr);//2.4过滤查询添加条件

filterQuery.addCriteria(criteria);//2.5查询添加过滤查询

simpleHighlightQuery.addFilterQuery(filterQuery);

System.out.println("分类过滤查询:"+categoryStr);

}//3.过滤查询条件=====品牌相关

String brand = (String) searchMap.get("brand");if (brand != null){

SimpleFilterQuery filterQuery= newSimpleFilterQuery();

Criteria criteria= new Criteria("item_brand");

criteria=criteria.contains(brand);

filterQuery.addCriteria(criteria);

simpleHighlightQuery.addFilterQuery(filterQuery);

System.out.println("品牌过滤查询:"+brand);

}//4.过滤查询条件=====规格相关

Map specMap = (Map) searchMap.get("spec");if (specMap != null){for(String s : specMap.keySet()) {

SimpleFilterQuery filterQuery= newSimpleFilterQuery();

Criteria criteria= new Criteria("item_spec_"+s);

criteria=criteria.contains(specMap.get(s));

filterQuery.addCriteria(criteria);

simpleHighlightQuery.addFilterQuery(filterQuery);

System.out.println("规格滤查询:"+s);

}

}//4.过滤条件查询=====价格相关

String price = (String) searchMap.get("price");//0-199

if (price != null){//1500-2000

String[] prices = price.split("-");//过滤条件增加起始价格

SimpleFilterQuery filterQuery1 = newSimpleFilterQuery();

Criteria criteria1= new Criteria("item_price");

criteria1= criteria1.greaterThanEqual(prices[0]); //大于等于起始价格

filterQuery1.addCriteria(criteria1);

simpleHighlightQuery.addFilterQuery(filterQuery1);//过滤条件增加结束价格

if(!"*".equals(prices[1])){ //防止3000元以上的*号

SimpleFilterQuery filterQuery2 = newSimpleFilterQuery();

Criteria criteria2= new Criteria("item_price");

criteria2= criteria2.lessThanEqual(prices[1]); //小于等于结束价格

filterQuery2.addCriteria(criteria2);

simpleHighlightQuery.addFilterQuery(filterQuery2);

}

System.out.println("价格过滤查询:"+price);

}//5.价格升降序=======价格升降序,前端设置默认是desc

String sort = (String) searchMap.get("sort");//定义排序对象

Sort orders = null;if ("DESC".equalsIgnoreCase(sort)){//降序查询 :参数1-指定升降序 参数2-指定域

orders = new Sort(Sort.Direction.DESC,"item_price");

System.out.println("价格降序过滤查询:"+sort);

}else{

orders= new Sort(Sort.Direction.ASC,"item_price");

System.out.println("价格升序过滤查询:"+sort);

}//为查询添加排序

simpleHighlightQuery.addSort(orders);//6.分页相关

Integer pageSize = (Integer) searchMap.get("pageSize");

Integer pageNo= (Integer) searchMap.get("pageNo");//设置分页参数 :起始索引和每页条数

simpleHighlightQuery.setOffset((pageNo-1)*pageSize);

simpleHighlightQuery.setRows(pageSize);//查询

HighlightPage tbItems =solrTemplate.

queryForHighlightPage(simpleHighlightQuery, TbItem.class);//将高亮设置后的属性赋值给查出的内容

List contents =tbItems.getContent();for(TbItem content : contents) {

List highlights =tbItems.getHighlights(content);if (highlights.size()>0){//防止数组空内容

List snipplets = highlights.get(0).getSnipplets();if (snipplets.size()>0){//防止空内容

content.setTitle(snipplets.get(0));

}

}

}//构建返回的map对象

Map returnMap = newHashMap();

returnMap.put("rows", contents);//分页需要总记录数

returnMap.put("total",tbItems.getNumberOfElements());returnreturnMap;

}/*** 根据商品的id(spu)将商品(sku)导入到solr索引库中

*@paramids 商品的id数组(spu)*/@Overridepublic voidimportItemsByGoodsId(Long[] ids) {//goods的所有ids,查询其列表导入到solr索引库

TbItemExample example = newTbItemExample();

example.createCriteria().andGoodsIdIn(Arrays.asList(ids));

List tbItems =itemMapper.selectByExample(example);//将数据存入solr索引库

solrTemplate.saveBeans(tbItems);

solrTemplate.commit();

System.out.println("solr库导入了商品:"+tbItems.size()+"个");

}/*** 根据商品的id(spu)将商品(sku)从solr索引库中删除

*@paramids 商品的id数组(spu)*/@Overridepublic voiddelItemsByGoodsId(Long[] ids) {//id是goods的id

TbItemExample example = newTbItemExample();

example.createCriteria().andGoodsIdIn(Arrays.asList(ids));

List tbItems =itemMapper.selectByExample(example);//循环删除sku(solr索引库中的)

for(TbItem tbItem : tbItems) {

solrTemplate.deleteById(tbItem.getId().toString());

}

solrTemplate.commit();

System.out.println("solr库删除了商品:"+tbItems.size()+"个");

}

}

关注微信公众号,  随时随地学习

你可能感兴趣的:(Java接收solr动态域)