SpringBoot2.x 整合Solr6.x

Posted 在奋斗的大道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot2.x 整合Solr6.x相关的知识,希望对你有一定的参考价值。

第一步:pom.xml 添加相关jar包依赖

<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.zzg</groupId>
	<artifactId>sb-solr</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.2.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<!-- 集中定义管理依赖版本号 -->
		<commons-lang.version>2.6</commons-lang.version>
		<commons-codec.version>1.10</commons-codec.version>
		<commons-lang3.version>3.9</commons-lang3.version>
		<commons-net.version>3.6</commons-net.version>
		<commons-io.version>2.6</commons-io.version>
		<commons-collections.version>3.2.1</commons-collections.version>
		<commons-text.version>1.8</commons-text.version>
		<common-fileupload.version>1.3.1</common-fileupload.version>
		<servlet-api.version>3.1.0</servlet-api.version>
		<httpclient.version>4.5.2</httpclient.version>
		<fastjson.version>1.2.48</fastjson.version>
	</properties>

	<dependencies>
		<!--starter -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
			<exclusions>
				<exclusion>
					<groupId>ch.qos.logback</groupId>
					<artifactId>logback-classic</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- test -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!--web -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			 <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
			 </exclusions>
		</dependency>
		<!-- 整合log4j 日志  -->
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j</artifactId>
             <version>1.3.8.RELEASE</version>
        </dependency>
        
		<!-- 数据库连接池druid -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>
		<!--mysql 驱动程序 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!-- oracle 驱动程序 -->
		<dependency>
			<groupId>com.oracle.jdbc</groupId>
			<artifactId>com.springsource.oracle.jdbc</artifactId>
			<version>10.2.0.2</version>
		</dependency>
		<!-- Swagger2 集成 -->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.7.0</version>
			<exclusions>
				<exclusion>
					<groupId>com.fasterxml.jackson.core</groupId>
					<artifactId>jackson-annotations</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.7.0</version>
		</dependency>

		<!-- 数据库文档自动生成 -->
		<dependency>
			<groupId>cn.smallbun.screw</groupId>
			<artifactId>screw-core</artifactId>
			<version>1.0.5</version>
			<exclusions>
				<exclusion>
					<groupId>ch.qos.logback</groupId>
					<artifactId>logback-classic</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.freemarker</groupId>
			<artifactId>freemarker</artifactId>
			<version>2.3.30</version>
		</dependency>

		<!--lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
		<!-- mybatis-plus 集成 -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.4.1</version>
		</dependency>
		<!--validation -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
		<!-- solr 客户端集成 -->
		<dependency>
			<groupId>org.apache.solr</groupId>
			<artifactId>solr-solrj</artifactId>
			<version>4.10.1</version>
		</dependency>
		<!--common-lang 常用工具包 -->
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>${commons-lang.version}</version>
		</dependency>
		<!--commons-lang3 工具包 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>${commons-lang3.version}</version>
		</dependency>

		<!--commons-codec 加密工具包 -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>${commons-codec.version}</version>
		</dependency>
		<!--commons-net 网络工具包 -->
		<dependency>
			<groupId>commons-net</groupId>
			<artifactId>commons-net</artifactId>
			<version>${commons-net.version}</version>
		</dependency>
		<!--common-io 工具包 -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>${commons-io.version}</version>
		</dependency>
		<!--common-collection 工具包 -->
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>${commons-collections.version}</version>
		</dependency>
		<!--common-fileupload 工具包 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>${common-fileupload.version}</version>
		</dependency>
		<!-- common-text 工具包 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-text</artifactId>
			<version>${commons-text.version}</version>
		</dependency>
		<!-- 集成servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${servlet-api.version}</version>
		</dependency>
		<!-- 集成Apache HttpClient -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>${httpclient.version}</version>
		</dependency>
		<!-- 集成fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>${fastjson.version}</version>
		</dependency>
	</dependencies>
</project>

第二步:application.poperties 配置数据库和solr 索引参数

# 指定服务端口
server.port=8015
# 指定服务 名称
server.servlet.context-path=/solr
#mybatis xml 文件配置
mybatis.mapper-locations=classpath*:mapper/*Mapper.xml
mybatis.type-aliases-package=com.zzg.entity
# MyBatis Oracle 配置
spring.datasource.url=jdbc:oracle:thin:127.0.0.1:1521:orcl
spring.datasource.username=zzg
spring.datasource.password=zzg
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
# Druid 配置
# 初始化时建立物理连接的个数
spring.datasource.druid.initial-size=5
# 最大连接池数量
spring.datasource.druid.max-active=30
# 最小连接池数量
spring.datasource.druid.min-idle=5
# 获取连接时最大等待时间,单位毫秒
spring.datasource.druid.max-wait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
#spring.datasource.druid.time-between-eviction-runs-millis=60000
# 连接保持空闲而不被驱逐的最小时间
#spring.datasource.druid.min-evictable-idle-time-millis=300000
# 用来检测连接是否有效的sql,要求是一个查询语句(mybatis)
# spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
# 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
#spring.datasource.druid.test-while-idle=true
# 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
#spring.datasource.druid.test-on-borrow=false
# 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
#spring.datasource.druid.test-on-return=false
# 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
#spring.datasource.druid.pool-prepared-statements=true
# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
#spring.datasource.druid.max-pool-prepared-statement-per-connection-size=50
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计
#spring.datasource.druid.filters=stat,wall
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
#spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
# 合并多个DruidDataSource的监控数据
#spring.datasource.druid.use-global-data-source-stat=true
# 配置sql 注入方式
#spring.datasource.druid.filters=stat
# 重新设置cors 规则
spring.main.allow-bean-definition-overriding=true

#配置solr 连接参数
solr.archinfo.url=http://127.0.0.1:8314/solr-webapp/archInfo
solr.archinfo.maxRetries=2
solr.archinfo.connectionTimeout=5000

第二步:项目相关配置参数

MyBatis-plus 分页参数配置
 

package com.zzg.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;

/**
 * mybatis-plus 配置对象
 * @author zzg
 *
 */
@Configuration
public class MybatisPlusConfig {
	/**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("oracle");
        return page;
    }
}

Apache Solr 指定索引实例化

package com.zzg.config;

import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zzg.solr.entity.ApacheSolrArchInfoEntity;

@Configuration
public class ApacheSolrConfig {
	@Autowired
	private ApacheSolrArchInfoEntity archInfo;
	
	/**
     * 案卷索引对象实例化
     */
    @Bean(value="apacheSolrArchInfo")
    public HttpSolrServer getHttpSolrServer() {
    	HttpSolrServer server =new HttpSolrServer(archInfo.getUrl());
    	// 设置响应解析器
    	server.setParser(new XMLResponseParser());
    	// 设置重试次数
    	server.setMaxRetries(archInfo.getMaxRetries());
    	// 设置超时时间
    	server.setConnectionTimeout(archInfo.getConnectionTimeout());
        return server;
    }

}

异步任务线程池配置

package com.zzg.config;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * solr 异步任务线程池配置对象
 * @author zzg
 *
 */
@Configuration
public class ThreadPoolExecutorConfigure {
	    @Bean(name = "solrExecutorAsync")
	    public Executor taskExecutor() {
	        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
	        executor.setCorePoolSize(10);//核心线程数
	        executor.setMaxPoolSize(10);//非核心线程数
	        executor.setQueueCapacity(200);//队列大小
	        executor.setKeepAliveSeconds(60);//非核心线程空闲时间(秒)
	        executor.setThreadNamePrefix("solrExecutor-");//线程前缀
	        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());//拒绝策略-丢弃
	        //该方法就是这里的关键,用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean,这样这些异步任务的销毁就会先于Redis线程池的销毁。
	        executor.setWaitForTasksToCompleteOnShutdown(true);
	        //该方法用来设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
	        executor.setAwaitTerminationSeconds(60);
	        return executor;
	    }

}

第三步:Apache Solr 索引库通用实例化对象定义,Apache Solr 异步添加索引数据功能组件定义。

package com.zzg.solr.entity;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Data;

/**
 * Apache Solr 连接实体对象
 * @author zzg
 *
 */
@Component
@ConfigurationProperties(prefix = "solr.archinfo")
@Data
public class ApacheSolrArchInfoEntity {
	private String url;
	
	private Integer maxRetries;
	
	private Integer connectionTimeout;
}
package com.zzg.solr.async;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrInputDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import com.zzg.solr.service.ApacheSolrArchInfoService;

@Component
public class SolrAsyncCallback {
	private static Logger logger = LoggerFactory.getLogger(SolrAsyncCallback.class);
	
	@Autowired
	@Qualifier("apacheSolrArchInfo")
	private HttpSolrServer apacheSolrArchInfo;

	@Autowired
	private ApacheSolrArchInfoService apacheSolrArchInfoService;

	@Async("solrExecutorAsync")
	public void solrAddAsync(Long sid) throws InterruptedException {
		UpdateResponse response = null;

		SolrInputDocument doc = new SolrInputDocument();
		if (sid != null) {
			Map<String, Object> map = apacheSolrArchInfoService.getIndexDataForArch(sid);

			Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();

			while (entries.hasNext()) {

				Map.Entry<String, Object> entry = entries.next();

				System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
				doc.addField(entry.getKey(), entry.getValue());
			}

			if (!doc.isEmpty()) {
				try {
					System.out.println("doucument field:" + doc.toString());
					response = apacheSolrArchInfo.add(doc);
					apacheSolrArchInfo.commit();
				} catch (SolrServerException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error("异步任务更新索引异常信息:{}", e.getMessage(), e);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error("异步任务更新索引异常信息:{}", e.getMessage(), e);
				}
				response.getStatus();

			}
		}
	}

}

第四步:项目剩余包结构说明:entity\\Mapper\\service\\serviceImpl\\common

com.zzg.entity:实体对象定义

com.zzg.mapper:实体对象接口定义

com.zzg.service:实体对象服务接口定义

com.zzg.service.impl:实体对象服务接口实现类

com.zzg.commom:项目通用类(数据返回实体定义、分页参数实体对象定义、抽象Controller\\

String 工具类方法和资源读取类方法)

com.zzg.solr.service:索引与当前数据表业务关系封装

com.zzg.solr.util:索引数据查询展示工具类

 第五步:Solr 功能代码

package com.zzg.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrInputDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzg.common.AbstractController;
import com.zzg.common.PageParame;
import com.zzg.common.Result;
import com.zzg.common.StringUtil;
import com.zzg.entity.ArchInfo;
import com.zzg.service.ArchInfoService;
import com.zzg.solr.async.SolrAsyncCallback;
import com.zzg.solr.service.ApacheSolrArchInfoService;
import com.zzg.solr.util.SolrColumnUtil;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * solr 服务接口
 * 
 * @author zzg
 *
 */
@RestController
@RequestMapping("/api/solr")
public class ApacheSolrController extends AbstractController {
	private static Logger logger = LoggerFactory.getLogger(ApacheSolrController.class);

	@Autowired
	@Qualifier("apacheSolrArchInfo")
	private HttpSolrServer apacheSolrArchInfo;

	@Autowired
	private ApacheSolrArchInfoService apacheSolrArchInfoService;
	
	@Autowired
	private ArchInfoService archInfoService;
	
	// 异步任务线程池组件
	@Autowired
	private SolrAsyncCallback callBack;

	@ApiOperation(httpMethod = "POST", value = "案卷索引更新")
	@RequestMapping(value = "/addOrUpdate", method = { RequestMethod.POST })
	@ApiImplicitParams({
			@ApiImplicitParam(name = "sid", value = "案卷主键", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "archId", value = "案卷档号", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "archNo", value = "案卷整编号", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "archTitle", value = "案卷标题", required = false, dataType = "String", paramType = "query") })
	public Result addOrUpdate(@RequestBody Map<String, Object> parame) {
		UpdateResponse response = null;
		SolrInputDocument doc = new SolrInputDocument();
		if (ObjectUtils.isNotEmpty(parame)) {
			parame.forEach((k, v) -> {
				if (ObjectUtils.isNotEmpty(v)) {
					doc.addField(k, v);
				}

			});
		}

		if (!doc.isEmpty()) {
			try {
				response = apacheSolrArchInfo.add(doc);
				apacheSolrArchInfo.commit();
			} catch (SolrServerException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				logger.error("更新索引异常信息:{}", e.getMessage(), e);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				logger.error("更新索引异常信息:{}", e.getMessage(), e);
			}
			int status = response.getStatus();
			if (status == 0) {
				return Result.ok();
			}

		}
		return Result.error("更新索引失败");
	}

	@ApiOperation(httpMethod = "POST", value = "案卷索引更新")
	@RequestMapping(value = "/update", method = { RequestMethod.POST })
	@ApiImplicitParams({
			@ApiImplicitParam(name = "sid", value = "案卷主键", required = false, dataType = "String", paramType = "query") })
	public Result update(@RequestBody Map<String, Object> parame) {
		UpdateResponse response = null;

		Long sid = null;
		Object obj = parame.get("sid");
		if (ObjectUtils.isNotEmpty(obj)) {
			sid = Long.valueOf(obj.toString());
		}

		SolrInputDocument doc = new SolrInputDocument();
		if (sid != null) {
			Map<String, Object> map = apacheSolrArchInfoService.getIndexDataForArch(sid);

			Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();

			while (entries.hasNext()) {

				Map.Entry<String, Object> entry = entries.next();

				System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
				doc.addField(entry.getKey(), entry.getValue());
			}

			if (!doc.isEmpty()) {
				try {
					System.out.println("doucument field:" + doc.toString());
					response = apacheSolrArchInfo.add(doc);
					apacheSolrArchInfo.commit();
				} catch (SolrServerException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error("更新索引异常信息:{}", e.getMessage(), e);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					logger.error("更新索引异常信息:{}", e.getMessage(), e);
				}
				int status = response.getStatus();
				if (status == 0) {
					return Result.ok();
				}

			}
		}

		return Result.error("更新索引失败");
	}
	@ApiOperation(httpMethod = "POST", value = "异步案卷索引创建")
	@RequestMapping(value = "/asyncUpdate", method = { RequestMethod.POST })
	public void asyncUpdate() {

		QueryWrapper<ArchInfo> queryWrapper = new QueryWrapper<ArchInfo>();
		Integer count = archInfoService.count();
		Integer pageSize  = 100;
		int pageNum = count / pageSize;
		int surplus = count % pageSize;// 是不是整除
		if (surplus > 0) {
			pageNum = pageNum + 1;
		}
		for (int i = 0; i < pageNum; i++) {
			// 传入i,pageSize进行业务逻辑处理
			Page<ArchInfo> page = new Page<ArchInfo>(i, pageSize);
			IPage<ArchInfo> list = archInfoService.page(page, queryWrapper);
			List<Long> sids = list.getRecords().stream().map(ArchInfo :: getSid).collect(Collectors.toList());
			if (CollectionUtils.isNotEmpty(sids)) {
				sids.stream().forEach(item->{
					try {
						callBack.solrAddAsync(item);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						logger.error("异步更新索引异常信息:{}", e.getMessage(), e);
					}
				});
			}
		}

	}
	

	@ApiOperation(httpMethod = "POST", value = "案卷索引检索")
	@RequestMapping(value = "/query", method = { RequestMethod.POST })
	@ApiImplicitParams({
			@ApiImplicitParam(name = "archId", value = "案卷档号", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "archNo", value = "案卷整编号", required = false, dataType = "String", paramType = "query"),
			@ApiImplicitParam(name = "archTitle", value = "案卷标题", required = false, dataType = "String", paramType = "query") })
	public Result query(@RequestBody Map<String, Object> parame) {
		// 构建查询条件
		SolrQuery query = new SolrQuery();
		// 设置查询分组
		query.setFacet(true);// 设置分组
		query.setFacetMinCount(1);// 设置为1,大于1才显示出分组
		query.set("facet.field",
				new String[] { "organizationCode", // 来源机构
						"assortNum", // 业务事项
						"archiveYear"// 归档年度
				});
		// 分页参数
		PageParame pageParame = this.initPageBounds(parame);
		query.setStart((pageParame.getPage() - 1) * pageParame.getLimit() > 0
				? (pageParame.getPage() - 1) * pageParame.getLimit() : 0);
		query.setRows(pageParame.getLimit());

		// 设置查询条件
		String condition = this.getQueryCondition(parame);
		if (StringUtils.isNotEmpty(condition)) {
			query.setQuery(condition);
		}

		// solr 查询
		QueryResponse queryResponse = null;
		try {
			queryResponse = apacheSolrArchInfo.query(query);

		} catch (SolrServerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("solr 检索异常:{}", e.getMessage(), e);
			return Result.error("业务案卷检索异常");
		}

		// solr 查询结果分页
		Page<Map> page = new Page<Map>();
		page.setRecords(transRowData(queryResponse.getResults()));
		page.setTotal(queryResponse.getResults().getNumFound());

		return Result.ok().setData(page).setData("faceFields", transFieldCount(queryResponse.getFacetFields()));
	}

	// 设置查询条件
	public String getQueryCondition(Map<String, Object> parameter) {
		StringBuilder builder = new StringBuilder();

		List<String> list = new ArrayList<String>();
		Iterator<Map.Entry<String, Object>> iterator = parameter.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, Object> entry = iterator.next();
			String str = "text:" + "*".concat(entry.getValue().toString()).concat("*");
			list.add(str);
		}

		for (int i = 0; i < list.size(); i++) {
			builder.append(list.get(i));
			if (i < list.size() - 1) {
				builder.append(" and ");
			}
		}
		return builder.toString();
	}

	/**
	 * 
	 * @Title: transRowData
	 * @Description: 业务档案全文检索结果表格转换
	 * @param: @param
	 *             list @return: void @throws
	 */
	@SuppressWarnings("rawtypes")
	private List<Map> transRowData(List<SolrDocument> list) {

		List result = new ArrayList(list.size());
		List<String> archColumnNames = SolrColumnUtil.getArchTableColumns();

		list.stream().forEach(item -> {
			LinkedHashMap rowData = new LinkedHashMap();

			String assortNum = String.valueOf(item.getFieldValue("assortNum"));
			String organizationCode = String.valueOf(item.getFieldValue("organizationCode"));
			rowData.put("sid", item.getFieldValue("sid"));
			archColumnNames.stream().forEach(columnName -> {
				rowData.put(columnName, item.getFieldValue(StringUtil.lineToHump(columnName)));
			});

			// 检索行扩展字段
			List<String> archExitColumnNames = SolrColumnUtil.getArchTableExitColumns(assortNum);
			Optional.ofNullable(archExitColumnNames).ifPresent(obj -> {
				List extend = new ArrayList();
				obj.stream().forEach(columnName -> {
					HashMap extendPro = new HashMap();
					extendPro.put(SolrColumnUtil.getColumnComment(columnName, organizationCode),
							item.getFieldValue(StringUtil.lineToHump(columnName)));
					extend.add(extendPro);
				});
				rowData.put("extend", extend);
			});
			result.add(rowData);
		});
		return result;
	}

	/**
	 * 
	 * @Title: transFieldCount @Description: json转换异常,分组统计结果转换. @param: @param
	 *         fields @param: @return @return: Map<String,List> @throws
	 */
	private Map<String, Map> transFieldCount(List<FacetField> fields) {

		LinkedHashMap<String, Map> rs = new LinkedHashMap<String, Map>();
		Optional.ofNullable(fields).ifPresent(obj -> {
			obj.stream().forEach(field -> {
				rs.put(field.getName(),
						field.getValues().stream().collect(Collectors.toMap(Count::getName, Count::getName)));
			});
		});
		

		return rs;
	}
}

第六步:Spring Boot2.x + Solr 项目源码

以上是关于SpringBoot2.x 整合Solr6.x的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot2.x整合quartz实现多任务定时执行

Springboot2.x最全整合系列(持续更新)

springboot2.x整合kafka

SpringBoot2.x整合WebSoket

springboot2.x整合quartz2.x.md

SpringBoot2.x 整合Redis和使用Redis缓存