项目集成ActiveMQ以及Solr全文检索服务

    最近项目需要消息中间件以及全文检索,考虑到需要近实时更新问题,没有采用Lucene 来写底层,直接用框架Solr好了

  1.消息队列的搭建

 下载ActiveMQ消息队列 地址:http://activemq.apache.org/activemq-5153-release.html


不同的操作系统进入不同文件夹中点击

启动 (我这里是win64)

项目配置

pom.xml 加入如下依赖  

   

    <!-- Activemq -->
    <dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-activemq</artifactId>
   </dependency>

MQ 消息发送实现类

package com.iking.message.provider.service.impl;
import javax.jms.Queue;
import javax.jms.Topic;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import com.alibaba.dubbo.config.annotation.Service;
import com.iking.common.api.message.service.TProducerService;
//楼主这里用的 dubbo 常规项目将这里换成spring的service注解即可

// @Service(version="1.0.0",interfaceName="com.iking.common.api.message.service.TProducerService")

@Service

public class TProducerServiceImpl implements TProducerService{ 

 //这个TProducerService 面向接口编程 所写的一个接口

	@Autowired
	private JmsMessagingTemplate jmsMessagingTemplate; //使用jms来发送消息
	
	/**
	 * 获取 Queue 队列
	 * @param key 需要监听的Queue
	 * */
	public Queue getQueue(String key){   //这个key  我这里采用人员id
		System.out.println(" 创建了一个Queue key: " + key);
		return new ActiveMQQueue(key);
	}
	
	/**
	 * point-to-point 消息生成  点对点 (p2p)
	 * @param message 消息对象  
	 * @param id 需要发送消息的用户
	 * */
	public void sendPointToPoint(Object message,String id) {
		Queue queue = this.getQueue(id);
		System.out.println(" 生成一条消息 :queue= " + queue);
		this.jmsMessagingTemplate.convertAndSend(queue,message);
	}
	
	
	/**
	 * 获取 Topic  主题
	 * */
	public Topic getTopic(String key)
	{
		System.out.println(" 创建了一个 Topic key: " + key);
		return new ActiveMQTopic(key);
	}
	
	/**
	 * pub/sub 发布/订阅
	 * */
	public void sendPubSub(Topic topic ,Object message) {
		System.out.println(" 生成一条消息 :queue= " + topic);
		this.jmsMessagingTemplate.convertAndSend(topic,message);
	}
}


配置文件添加如下信息

#ActiveMQ 代理地址   代理服务器未启动无效 
#集群配置 主tcp服务器地址   备用tcp服务器地址   
spring.activemq.broker-url=failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61616)?timeout=3000&randomize=false
#username  代理服务器 用户名
spring.activemq.user=admin
#password  代理服务器 密码
spring.activemq.password=admin
#切换当前模式  point-to-point and pub/sub 默认为 false为点对点,true为发布订阅
spring.jms.pub-sub-domain=false 
#是否启用内存模式 不开启内存模式 
spring.activemq.in-memory=false
#信任所有的包
spring.activemq.packages.trust-all=true 
#是否替换默认的connectionFactory
#spring.activemq.pool.enabled=false
#最大连接数
#spring.activemq.pool.max-connections=50
#超时时间
#spring.activemq.pool.expiry-timeout=10000
#空闲时间
#spring.activemq.pool.idle-timeout=30000
#会话缓存大小
#spring.activemq.pool.session-cache-size=100

下来还需要页面配置  应为此处楼主项目 需要将消息实时推送到用户手中 所以在页面用JS创建消费者

应为每个用户都需要实时接受消息 ,并切一登录也需要立即接受消息  所以应该写在登录成功后看到的第一个页面我这里是home页面

页面需要引入一个stomp.js  百度搜索即可



就是这个js




1=前后固定写法 中间路径端口自行配置 本地的话127.0.0.1 或者localhost 即可

2=帐号密码

3=用户登录会存储当前用户的id  我这里则用这个用户id 连接mq  应为后台也是以用户id 为队列id来创建推送消息的

4=后台推送的数据如下图箭头所对应的参数

5=开始连接mq

mq 管理页面

name 我这里设置用户id为name 前台页面也以此为key来创建连接消费消息

Number Of Pending Messages  等待消费的消息 “这个是当前未出队列的数量。可以理解为总接收数-总出队列数” 

Number Of Consumers  消费者 “这个是消费者端的消费者数量” 

Messages Enqueued  进入队列的消息  “进入队列的总数量,包括出队列的。 这个数量只增不减” 

Messages Dequeued  出了队列的消息  “可以理解为是消费这消费掉的数量”


至此mq搭建完成

2.solr全文检索

solr 版本 4.10.3

tomcat 8(tmcat7及以上) jkd1.8(jdk1.7及以上即可)

solr 自带容器 但自处并不适用默认容器  先将默认容器改为tmocat


将此war包解压   将解压后的文件夹复制到tomcat webapps目录下


将solr 此目录下 ext问价夹中的所有jar包复制 到tmocat solr应用 web-inf/lib 内




将 solr原目录下 的 dist 和 contrib 复制到  tomcat wenpapps/solr路径下



在tomcat solr 应用内 新建 索引库 solr_home


然后新建solr_1

将solr原路径下的 solr文件夹内的所有东西 复制到tomcat solr_1 文件加中(这是在搭建solr_home)



复制到


打开 tomcat  solr 应用 web-inf 内的web.xml 进行配置


进行如下配置


至此solr 服务独立搭建完成  可以运行这个tmocat了

打开http://127.0.0.1:20188/solr/ 页面进行验证是否搭建成功

看到如下页面即为搭建成功



简单介绍这个管理页面



增加的时候要先手动创建响应文件夹


复制这个即可




接下来 让项目连接这个solr服务

下面上代码

先配置 配置 配置

pom.xml 加入如下信息

    
<!-- solr 全文检索 -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-solr</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>4.10.3</version>
</dependency>

指定版本  我这里用的 spring boot 但依旧指定版本 solr lucene 这东西版本变更太快

spring 核心概念 一切皆为 bean

所以为了符合这个理念

solr配置也采用bean的方式

package com.iking.outside.provider.config;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.core.env.Environment;



@Configuration
public class SolrConfig {
	@Autowired
	private Environment env;  //用于读取 spring boot 配置文件
	@Bean
	public SolrServer getSolrServer() {
		System.out.println("solr 依赖注入启动...");
		return new HttpSolrServer(env.getProperty("solr.service.url"));

 //这个key  随便写的  但别用spring 开头 应为spring 也整合了solr 用spring 开头 可能会引起意想不到的错误

	}
}


application.properties 文件加入如下信息

#solr 

solr.service.url=http://localhost:20188/solr/


solr 服务实现类  依旧的面向接口编程

接口:

package com.iking.common.api.outsid.service;
import java.util.List;
import java.util.Map;
public interface ISolrService {
	
	/**
	 * @warning 业务插入执行完毕 请调用 commit(); 
	 * 增加文档集合
	 * @param list 业务实体数据集合
	 * */
	public void addList(List<?> list) ;
	/**
	 * @warning 业务插入执行完毕 请调用 commit(); 
	 * 增加文档
	 * @param entity 业务实体对象
	 * */
	public void add(Object entity) ;
	
	/**
	 * @warning 业务删除执行完毕 请调用 commit(); 
	 * 删除文档
	 * @param entity 业务实体对象
	 * */
	public void deleteDocument(Object entity)  ;
	
	/**
	 * @warning 业务更新执行完毕 请调用 commit(); 
	 * 修改文档
	 * @param entity 业务数据对象
	 * */
	public void updateDocument(Object entity) ;
	
	/**
	 * 提交
	 * */
	public void commit();
	/**
	 * 所有涉及 字段名称 请遵循如下规则  否则会造成数据无法查询<br/><br/>
	 * name == 'id' 											则传入即可,无需处理
	 * <br/>
	 * <br/>
	 * type == (byte(Byte) || short(Short) || Integer(int) 		 则 name += "_i"
	 * <br/>
	 * <br/>
	 * type == Long(long) 								 		 则 name += "_l"
	 * <br/>
	 * <br/>
	 * type == Float(float) 							    	 则 name += "_f"
	 * <br/>
	 * <br/>
	 * type == Double(double)									 则 name += "_d"
	 * <br/>
	 * <br/>
	 * type == Boolean(boolean)									 则 name += "_b"
	 * <br/>
	 * <br/>
	 * type == (Character(char)||String)						 则 name += "_s"
	 * <br/>
	 * <br/>
	 * type == Date												 则 name += "_dt"
	 * <br/>  
	 * <br/>
	 * 查询
	 * @param param 多条件集合
	 * @param fieldName 关键词字段名称   
	 * @param q 关键词  
	 * @param isHighlight 是否高亮显示
	 * <p>
	 * 添加过滤条件: k=fq v=过滤字段名称&过滤字段值
	 * <br/>
	 * <br/>
	 * 添加排序: k=sort v=排序条件字段名称&ASC/DESC
	 * <br/>
	 * <br/>
	 * 添加分页: k=page,v=开始数&显示行数
	 * <br/>
	 * <br/>
	 * 默认查询域: k=df v=默认查询与字段名称&字段值  --- 已禁用   
	 * <br/>
	 * <br/>
	 * 指定查询域: k=fl v=查询域字段名称1&查询域字段名称2&查询域字段名称3&....查询域字段名称n
	 * <br/>
	 * <br/>
	 * 高亮: 
	 * <br/>
	 * <br/>
	 *    高两域  默认未关键字 q 所对应的域  fieldName 
	 * <br/>
	 *    字体颜色:k=h&color v=颜色具体值  例如  red blue 
	 * <br/>
	 * <br/>
	 *    字体大小:k=h&size  v=具体数值
	 * <br/>
	 * <br/>
	 *    设置高亮请开启 isHighlight=true	 否则不生效 默认红色
	 * </p>
	 * @return List<?> 具体类型集合
	 * */
	public List<?> solrSearch(Map<String,String> param,String fieldName,String q,boolean isHighlight,Class<?>[] entitys) ;
	/**
	 * @warning 此方法禁用,业务删除执行完毕 请调用 commit(); 
	 * 删除索引库
	 * @param entity 业务实体对象
	 * @deprecated
	 * */
	public void deleteDocumentAll( );
	
	/**
	 * 回滚
	 * */
	public void rollback();
}

*****************************************实现类*******************************

package com.iking.outside.provider.service;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.dubbo.config.annotation.Service;
import com.iking.common.api.outsid.service.ISolrService;

/**
 * solr 增删改查 实现类
 * @author 418233
 * @date 2018年4月3日 10:51:27
 * @version 1.0
 * */

//@Service(version="1.0.0",interfaceName="com.iking.common.api.outsid.service.ISolrService",timeout=50000) //换成spring 的Service 注解即可

@Service

public class SolrServiceImpl implements ISolrService {
	
	@Autowired
	private SolrServer solrService; //这里自动装配的 就是刚才配置的bean  SolrConfig.getSolrServer()方法返回的bean
	
	/**
	 * @warning 业务插入执行完毕 请调用 commit(); 
	 * 增加文档集合
	 * @param list 业务实体数据集合
	 * */
	public void addList(List<?> list){
		List<SolrInputDocument> docs = new ArrayList<>();
		for (Object obj : list) {
			docs.add(reflect2Doc(obj));
		}
		this.add(docs);
	}
	
	/**
	 * @warning 业务插入执行完毕 请调用 commit(); 
	 * 增加文档
	 * @param entity 业务实体对象
	 * */
	public void add(Object entity) {
		this.add(reflect2Doc(entity));
	}
	
	/**
	 * @warning 业务删除执行完毕 请调用 commit(); 
	 * 删除文档
	 * @param entity 业务实体对象
	 * */
	public void deleteDocument(Object entity){
		Class<?> clazz = entity.getClass();
		for(Field f : clazz.getDeclaredFields()){
			f.setAccessible(true);
			String fileName = f.getName();
			fileName += getFieldNameSuffix(f.getType());
			Object val = null;
			
			try {
				val = f.get(entity);
			} catch (IllegalArgumentException | IllegalAccessException e1) {
				throw new RuntimeException(" SolrServiceImpl.deleteDocument(...) 失败! \r  " + e1);
			}
			
			if(val == null) continue;
			
			try {
				this.solrService.deleteByQuery(fileName + ":" + val,1000);
			} catch (Exception e) {
				throw new RuntimeException(" SolrServiceImpl.deleteDocument(...) 失败! \r  " + e);
			}
		}
	}
	
	/**
	 * @warning 此方法禁用,业务删除执行完毕 请调用 commit(); 
	 * 删除索引库
	 * @param entity 业务实体对象
	 * @deprecated
	 * */
	public void deleteDocumentAll( ){
		try {
			this.solrService.deleteByQuery("*:*");
		} catch (SolrServerException | IOException e) {
			throw new RuntimeException(" SolrServiceImpl.deleteDocumentAll() 失败! \r  " + e);
		}
		System.out.println(" 索引库删除成功! 请重新创建! ");
	}
	
	/**
	 * @warning 业务更新执行完毕 请调用 commit(); 
	 * 修改文档
	 * @param entity 业务数据对象
	 * */
	public void updateDocument(Object entity) {
		this.add(entity);
	}
	
	/**
	 * 所有涉及 字段名称 请遵循如下规则  否则会造成数据无法查询<br/><br/>
	 * name == 'id' 											则传入即可,无需处理
	 * <br/>
	 * <br/>
	 * type == (byte(Byte) || short(Short) || Integer(int) 		 则 name += "_i"
	 * <br/>
	 * <br/>
	 * type == Long(long) 								 		 则 name += "_l"
	 * <br/>
	 * <br/>
	 * type == Float(float) 							    	 则 name += "_f"
	 * <br/>
	 * <br/>
	 * type == Double(double)									 则 name += "_d"
	 * <br/>
	 * <br/>
	 * type == Boolean(boolean)									 则 name += "_b"
	 * <br/>
	 * <br/>
	 * type == (Character(char)||String)						 则 name += "_s"
	 * <br/>
	 * <br/>
	 * type == Date												 则 name += "_dt"
	 * <br/>  
	 * <br/>
	 * 查询
	 * @param param 多条件集合
	 * @param q 关键词  
	 * @param fieldName 关键词字段名称   
	 * @param isHighlight 是否高亮显示
	 * @param entity 实体类型
	 * <p>
	 * 添加过滤条件: k=fq v=过滤字段名称&过滤字段值
	 * <br/>
	 * <br/>
	 * 添加排序: k=sort v=排序条件字段名称&ASC/DESC
	 * <br/>
	 * <br/>
	 * 添加分页: k=page,v=开始数&显示行数
	 * <br/>
	 * <br/>
	 * 默认查询域: k=df v=默认查询与字段名称&字段值  --- 已禁用   
	 * <br/>
	 * <br/>
	 * 指定查询域: k=fl v=查询域字段名称1&查询域字段名称2&查询域字段名称3&....查询域字段名称n
	 * <br/>
	 * <br/>
	 * 高亮: 
	 * <br/>
	 * <br/>
	 *    高两域  默认未关键字 q 所对应的域  fieldName 
	 * <br/>
	 *    字体颜色:k=h&color v=颜色具体值  例如  red blue 
	 * <br/>
	 * <br/>
	 *    字体大小:k=h&size  v=具体数值
	 * <br/>
	 * <br/>
	 *    设置高亮请开启 isHighlight=true	 否则不生效 默认红色
	 * </p>
	 * @return List<?> 具体类型集合
	 * */
	public List<?> solrSearch(Map<String,String> param,String fieldName,String q,boolean isHighlight,Class<?>[] entitys) {
		return this.search(param, fieldName, q, isHighlight,entitys);
	}
	
	/**
	 * 提交
	 * */
	public void commit() {
		try {
			solrService.commit(true,true);
		} catch (SolrServerException | IOException e) {
			throw new RuntimeException(" SolrServiceImpl.commit() 提交失败! \r " + e);
		}
	}
	
	/**
	 * 回滚
	 * */
	public void rollback(){
		try {
			solrService.rollback();
		} catch (SolrServerException | IOException e) {
			throw new RuntimeException(" SolrServiceImpl.rollback() 回滚失败! \r " + e);
		}
	}
	
	/**
	 * @param bean 业务数据对象
	 * @param fieldName 字段名称
	 * @param clazz 实体类型
	 * */
	private SolrInputDocument reflect2Doc(Object bean){
		SolrInputDocument doc = null;
		Class<?> entity = bean.getClass();
		Field[] fields = entity.getDeclaredFields();
		doc = new SolrInputDocument();
		for (Field f : fields) {
			f.setAccessible(true);
			if(!isFinal(f.getModifiers())){
				try {
					if("fId".equals(f.getName())){
						this.setField(doc,"id", f.get(bean), f.getType());
					}else{
						this.setField(doc, f.getName(), f.get(bean), f.getType());
					}
				} catch (IllegalArgumentException | IllegalAccessException e) {
					throw new RuntimeException(" SolrServiceImpl.reflect2Doc 反射获取bean方法返回值失败! " + e);
				}
			}
		}
		doc.setField("classes_s", entity.toString()); //增加类型信息
		return doc;
	}
	
	/**
	 * 设置域名
	 * */
	private void setField(SolrInputDocument doc,String name,Object val,Class<?> type){
		
		if(!"id".equals(name)){
			name += getFieldNameSuffix(type);
		}
		doc.setField(name, val);
	}
	
	/**
	 * 获取字段后缀
	 * */
	private String getFieldNameSuffix(Class<?> type){
		String suffix = "";
		if (type == Byte.class || type == byte.class) {
			suffix = "_i";
		} else if (type == Short.class || type == short.class) {
			suffix = "_i";
		} else if (type == Integer.class || type == int.class) {
			suffix = "_i";
		} else if (type == Long.class || type == long.class) {
			suffix = "_l";
		} else if (type == Float.class || type == float.class) {
			suffix = "_f";
		} else if (type == Double.class || type == double.class) {
			suffix = "_d";
		} else if (type == Boolean.class || type == boolean.class) {
			suffix = "_b";
		} else if (type == Character.class || type == char.class) {
			suffix = "_s";
		} else if (type == String.class) {
			suffix = "_s";
		} else if (type == Date.class) {
			suffix = "_dt";
		}
		return suffix;
	}
	
	/**
	 * 是否被final修饰
	 * */
	private boolean isFinal(int modifiers){
		return (modifiers & Modifier.FINAL) != 0;
	}
	
	/**
	 * @param docs 文档集合
	 * */
	private void add(List<SolrInputDocument> docs){
		try {
			solrService.add(docs);
		} catch (SolrServerException | IOException e) {
			throw new RuntimeException(" SolrServiceImpl.add(List<SolrInputDocument> docs)  增加失败! 请检查 docs 参数 " + e);
		}
	}
	
	/**
	 * @param docs 文档
	 * */
	private void add(SolrInputDocument doc){
		try {
			solrService.add(doc);
		} catch (SolrServerException | IOException e) {
			throw new RuntimeException(" SolrServiceImpl.add(SolrInputDocument doc)  增加失败! 请检查 doc 参数 " + e);
		}
	}
	
	/**
	 * 查询
	 * @param param 多条件集合
	 * @param q 关键词  
	 * @param fieldName 关键词字段名称   
	 * @param isHighlight 是否高亮显示
	 * @param entity 实体类型
	 * <br/>
	 * */
	private List<?> search(Map<String,String> param,String fieldName,String q,boolean isHighlight,Class<?>[] entitys){
		
		if(param == null)param = new HashMap<>();
		//这里对应刚才那个管理页面的选项
		String[] fqVal = existence(param.get("fq"));//过滤条件  
		
		String[] sortVal = existence( param.get("sort"));//排序
		
		String[] pageVal = existence(param.get("page"));//分页
		
		String[] flVal = existence(param.get("fl"));//指定查询域
		
		String[] hColor = existence(param.get("h&color"));//高亮字体颜色
		
		String[] hSize = existence(param.get("h&size"));//高亮字体颜色
		
		
		SolrQuery solrQuery = new SolrQuery();
		//设置 条件
		//关键词
		if(StringUtils.isBlank(fieldName)&& StringUtils.isBlank(q)){
			solrQuery.setQuery("*:*");//查所有
		}else{
			solrQuery.setQuery(fieldName + ":*" + q + "*");
		}
		
		//过滤条件
		if(fqVal != null)
			solrQuery.set("fq",fqVal[0] + ":"+ fqVal[1]);
		
		//排序
		if(sortVal != null){
			ORDER order = "ASC".equals(sortVal[1]) ? ORDER.asc : "DESC".equals(sortVal[1]) ? ORDER.desc : ORDER.asc;
			solrQuery.addSort(sortVal[0] , order);
		}
		
		//分页
		if(pageVal != null){
			solrQuery.setStart(Integer.parseInt(pageVal[0]));
			solrQuery.setRows(Integer.parseInt(pageVal[1]));
		}else{
			solrQuery.setStart(0);
			solrQuery.setRows(10);
		}
		
		//默认查询域
		//solrQuery.set("df","*");
		
		//指定查询域
		if(flVal != null){
			StringBuilder sbl = new StringBuilder();
			
			for(String str : flVal){
				sbl.append(str + ",");
			}
			sbl.delete(sbl.length()-1,sbl.length());
			solrQuery.set("fl",sbl.toString());
		}
		
		//高亮
		if(isHighlight){
			//开启高亮
			solrQuery.setHighlight(true);
			//设置高亮域
			solrQuery.addHighlightField(fieldName);
			//高亮前缀
			//字体大小 ,字体颜色
			String size = StringUtils.isNotBlank(hColor[0]) ? hColor[0] : "red";
			String color = StringUtils.isNotBlank(hSize[0]) ? hSize[0] : "5";
			solrQuery.setHighlightSimplePre("<span style='color:'" + color + "',size:'"+size+"'>");
			//高亮后缀
			solrQuery.setHighlightSimplePost("</span>");
		}
		
		//执行查询
		QueryResponse response;
		try {
			response = solrService.query(solrQuery);
		} catch (SolrServerException e) {
			 throw new RuntimeException(" SolrServiceImpl.search(...) 失败! 获取query 异常  \r " + e); 
		}
		//文档结果集
		SolrDocumentList docs = response.getResults();
		
		//获取高亮结果集
		Map<String,Map<String,List<String>>> map = null;
		if(isHighlight)
			map = response.getHighlighting();
		//map k id v map
		//map k 域名 v list
		//list 结果
		
		//总行数
		long count = docs.getNumFound();
		System.out.println("匹配文档数 : " + count);
		
		int index = 0;
		List<Object> result = new ArrayList<>();
		
		for (SolrDocument solrDocument : docs) {
			//判断类型
			Class<?> entity = null;
			Object classes = solrDocument.get("classes_s");
			for (Class<?> clazz : entitys) {
				if(classes.equals(clazz.toString())){
					entity = clazz;
					break;
				}
			}
			
			Object bean;
			try {
				bean = entity.newInstance();
			} catch (InstantiationException | IllegalAccessException e) {
				throw new RuntimeException(" SolrServiceImpl.search(...) 失败! 反射获取实例失败  请检查 entity参数是否为空!  \r " + e);
			}
			
			for (Field f : entity.getDeclaredFields()) {
				f.setAccessible(true);
				if(!isFinal(f.getModifiers())){ //对于 final 修饰字段不予处理
					String k = f.getName();
					
					if(!"id".equals(k)) //对于id 字段不予获取后缀
						k += getFieldNameSuffix(f.getType()); //获取域名后缀
					
					if("fId_s".equals(k)){
						k = "id";
					}
					
					Object val = solrDocument.get(k);
				
					if(isHighlight && k.equals(fieldName)){
						Map<String,List<String>> map2 = map.get(solrDocument.get("id"));
						List<String> res = map2.get(fieldName);
						val = res.get(index);
					}
					
					this.setVal(bean, val+"", f.getType(), f);
				}
			}
			
			result.add(bean);
			index++;
		}
		
		return toRepeat(result);
	}
	
	/**
	 * 去重复
	 * */
	private List<?> toRepeat(List<Object> list){
		//去重复
		Set<?> set = new HashSet<>(list);
		Object[] obj = set.toArray();
		list = new ArrayList<>();
		for (Object o : obj) {
			list.add(o);
		}
		return list;
	}
	
	/**
	 * 分割参数
	 * */
	private String[] existence(String str){
		if(StringUtils.isNotBlank(str)){
			return str.split("&");
		}
		return null;
	}
	
	/**
	 * 设置属性
	 * @param bean
	 * @param val
	 * @param type
	 * @param f
	 * */
	private void setVal(Object bean, String val, Class<?> type, Field f) {
		try {
			
			if(StringUtils.isBlank(val) || "null".equals(val))return;
			
			if (type == Byte.class || type == byte.class) {
				f.set(bean, val.getBytes());
			} else if (type == Short.class || type == short.class) {
				f.set(bean, Short.parseShort(val));
			} else if (type == Integer.class || type == int.class) {
				f.set(bean, Integer.parseInt(val));
			} else if (type == Long.class || type == long.class) {
				f.set(bean, Long.parseLong(val));
			} else if (type == Float.class || type == float.class) {
				f.set(bean, Float.parseFloat(val));
			} else if (type == Double.class || type == double.class) {
				f.set(bean, Double.parseDouble(val));
			} else if (type == Boolean.class || type == boolean.class) {
				f.set(bean, Boolean.parseBoolean(val));
			} else if (type == Character.class || type == char.class) {
				f.set(bean, val);
			} else if (type == String.class) {
				f.set(bean, val);
			} else if (type == Date.class) {
				SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy",Locale.UK);
				f.set(bean, sdf.parse(val));
			}
		} catch (Exception e) {
			throw new RuntimeException("LuceneSearch setVal 出错! " + e);
		}
	}
}


controller 层如何使用solrServiceImpl 


先注入  此处注解换成 @Autowired 即可

先给个初始化方法

用于项目第一次启动构建索引库



查询




在这里面定义的


此处默认定义可以更改 不建议更改,若要更改需要详细学习 lucene 和solr 

简单说一下  某些类型的字段是否 会被索引检查到 以及是否排序等等  都在此处定义   一般来说默认定义足够你用了,







另外说几点

在进行业务方法的增删改 都需要调用一下solr的方法进行同步更新索引库   增加修改 调用add()即可  id相同即为修改 否则为新增

删除调用deleteDocument()即可  只需传入实体类  id字段需要有值

调用solr除查询方法外 请调用commit() 进行提交 ,rollbcak()进行回滚  来对索引库进行维护

不调用commit()提交 增删改是不会生效的.

至此 solr也全部完事了。






  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值