1.构建maven工程,使用spring boot ,添加如下依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<!-- 替换solrj为solr服务器的版本 -->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>6.5.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.编写查询接口IIndexSearch
public interface IndexSearch {
/**
* 根据id查询内容
*
* @param id
* @return
* @throws Exception
* @Title: search
* @Description:
* @return: PageData
*/
ResultEntity search(String id);
/**
* @param query
* @param isHight 是否高亮显示
* @return
*/
ResultEntity execute(SolrQuery query, boolean isHight);
}
public interface ISolrIndexSearch extends IndexSearch {
/**
* 获取SolrQuery对象
*
* @return
*/
SolrQuery getQuery();
/**
* 查询
*
* @param page 封装分页
* @param query 查询条件
* @param isHight 是否高亮显示
* @return
*/
ResultEntity search(Page page, SolrQuery query, boolean isHight);
}
- 抽象实现类AbstractSolrIndexSearch
public abstract class AbstractSolrIndexSearch implements ISolrIndexSearch {
private static final Logger LOGGER = Logger.getLogger(AbstractSolrIndexSearch.class);
@Resource(name = "solrClient")
protected SolrClient solr;
public abstract SolrQuery setHighlightHandle(SolrQuery query);
public abstract List<PageData> gethighlighDataList(SolrResponse response);
private ResultEntity putResponseMessage(List<PageData> datas, int responseTime, Page page) {
ResultEntity result = new ResultEntity();
result.setResults(datas);
result.setResponseTime(responseTime);
if (page != null) {
result.setPage(page);
}
return result;
}
private PageData getSolrDocumentToPageData(SolrDocument document) {
Iterator<Entry<String, Object>> it = document.iterator();
PageData pd = new PageData();
while (it.hasNext()) {
Entry<String, Object> entry = it.next();
pd.put(entry.getKey(), entry.getValue());
}
return pd;
}
private List<PageData> getDataFromSolrDocumentList(SolrDocumentList documents) {
List<PageData> dataList = Lists.newArrayList();
Iterator<SolrDocument> it = documents.iterator();
while (it.hasNext()) {
SolrDocument document = it.next();
PageData pds = getSolrDocumentToPageData(document);
dataList.add(pds);
}
return dataList;
}
@Override
public ResultEntity execute(SolrQuery query, boolean isHight) {
CompletableFuture<ResultEntity> completableFuture = CompletableFuture.supplyAsync(() -> {
return getDataAysc(query, isHight);
});
return completableFuture.join();
}
private ResultEntity getDataAysc(SolrQuery query, boolean isHight) {
ResultEntity result = new ResultEntity();
QueryResponse response;
List<PageData> datas;
try {
response = solr.query(query);
int responseTime = response.getQTime();
SolrDocumentList documents = response.getResults();
if (isHight) {
datas = gethighlighDataList(response);
} else {
datas = getDataFromSolrDocumentList(documents);
}
result = putResponseMessage(datas, responseTime, null);
LOGGER.info("查询参数:" + query.getQuery());
} catch (SolrServerException e) {
} catch (IOException e) {
}
return result;
}
@Override
public ResultEntity search(String id) {
long start = System.nanoTime();
SolrQuery query = new SolrQuery();
query.setQuery(SolrStatementUtils.generateBaseMatchStatement("id", id));
//ResultEntity result = execute(query);
ResultEntity result = getDataAysc(query, false);
long end = System.nanoTime();
LOGGER.info("异步查询用时:" + (end - start) + "s");
return result;
}
public ResultEntity search(Page page, SolrQuery query, boolean isHight) {
long start = System.nanoTime();
// 从page中获取传入的参数对象pagedata,是一个map数据结构
PageData pd = page.getPd();
int showCount = 0;
int currentPage = 0;
int totalResult = 0;
if (null != pd.getString("currentPage")) {
currentPage = Integer.parseInt(pd.getString("currentPage"));
}
if (currentPage == 0) {
currentPage = 1;
}
if (null != pd.getString("showCount")) {
showCount = Integer.parseInt(pd.getString("showCount"));
} else {
showCount = Const.SHOW_COUNT;
}
query.setStart(showCount * (currentPage - 1)).setRows(showCount);
if (isHight) {
query = setHighlightHandle(query);
}
ResultEntity result = execute(query, isHight);
page.setCurrentPage(currentPage);
page.setShowCount(showCount);
page.setTotalResult(totalResult);
page = makePage(page);
LOGGER.info("查询参数--" + pd);
LOGGER.info("查询:" + query.toQueryString());
long end = System.nanoTime();
LOGGER.info("方法执行时间:" + (end - start));
return result;
}
private Page makePage(Page page) {
page.getTotalPage();
page.setEntityOrField(true);
page.getPageStr();
return page;
}
}
- 子类去实现抽象类中的的抽象方法SolrIndexSearch
public class SolrIndexSearch extends AbstractSolrIndexSearch {
private static final Logger LOGGER = Logger.getLogger(SolrIndexSearch.class);
@Override
public SolrQuery getQuery() {
return new SolrQuery();
}
@Override
public SolrQuery setHighlightHandle(SolrQuery query) {
return null;
}
@Override
public List<PageData> gethighlighDataList(SolrResponse response) {
return null;
}
}
3.编写索引操作接口IndexeWriter
public interface IndexeWriter {
ResultEntity delete(List<String> ids);
ResultEntity delete(String id);
void deleteAll() throws Exception;
ResultEntity execute(SolrInputDocument document);
ResultEntity update(PageData document);
ResultEntity updataBatch(List<Object> documents);
ResultEntity write(List<Object> document);
ResultEntity write(PageData pd);
/**
* 创建索引
*
* @throws Exception
* @Title: createIndex
* @Description:
* @return: void
*/
void createIndex(String beginTime);
void commit();
void close();
/**
* 提交操作释放链接
*/
void detory();
}
- 抽象实现类AbstractSolrIndexWriter
public abstract class AbstractSolrIndexWriter implements IndexeWriter {
private static final Logger LOGGER = Logger.getLogger(AbstractSolrIndexWriter.class);
@Resource(name = "concurrentUpdateSolrClient")
protected SolrClient solr;
private SolrInputDocument getDocument(PageData pd) {
SolrInputDocument document = new SolrInputDocument();
Iterator it = pd.keySet().iterator();
while (it.hasNext()) {
String key = (String) it.next();
document.addField(key, pd.get(key));
}
return document;
}
private List<SolrInputDocument> getDocuments(List<PageData> pds) {
List<SolrInputDocument> datas = Lists.newArrayList();
for (PageData pd : pds) {
SolrInputDocument doc = getDocument(pd);
datas.add(doc);
}
return datas;
}
/**
* Title: delete
*
* @param id
* @throws Exception
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#delete(java.lang.String)
*/
@Override
public ResultEntity delete(String id) {
ResultEntity result = new ResultEntity();
UpdateResponse response;
try {
response = solr.deleteById(id);
int resopnseTime = response.getQTime();
result.setResponseTime(resopnseTime);
commit();
LOGGER.info("删除索引:编号--" + id + "用时:" + resopnseTime);
} catch (SolrServerException e) {
} catch (IOException e) {
}
return result;
}
@Override
public ResultEntity execute(SolrInputDocument document) {
CompletableFuture<ResultEntity> future = CompletableFuture.supplyAsync(() -> {
return executeAysc(document);
});
return future.join();
}
private ResultEntity executeAysc(SolrInputDocument document) {
ResultEntity result = new ResultEntity();
UpdateRequest request = new UpdateRequest();
request.setAction(ACTION.COMMIT, false, false);
request.add(document);
UpdateResponse response;
try {
response = request.process(solr);
int responseTime = response.getQTime();
result.setResponseTime(responseTime);
LOGGER.info("时间:" + new Date() + "用时:" + responseTime);
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* Title: write
*
* @param pd
* @throws Exception
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#write(com.jianong.springbootproject.util.PageData)
*/
@Override
public ResultEntity write(PageData pd) {
ResultEntity result = new ResultEntity();
SolrInputDocument d = getDocument(pd);
return execute(d);
}
/**
* Title: write
*
* @param document
* @return
* @see com.jianong.springbootproject.util.indexes.indexing.IndexeWriter#write(java.util.List)
*/
@Override
public ResultEntity write(List<PageData> documents) {
ResultEntity result = new ResultEntity();
List<SolrInputDocument> datas = getDocuments(documents);
int responseTime = 0;
try {
UpdateResponse response = solr.add(datas);
commit();
responseTime = response.getQTime();
result.setResponseTime(responseTime);
LOGGER.info("添加索引:" + documents.size() + "条--" + "用时:" + responseTime);
} catch (SolrServerException e) {
} catch (IOException e) {
}
return result;
}
private SolrInputDocument getUpdateDocument(PageData pd) {
Iterator<String> it = pd.keySet().iterator();
SolrInputDocument document = new SolrInputDocument();
while (it.hasNext()) {
String key = it.next();
if (Objects.equals("id", key)) {
document.setField(key, pd.get("id"));
} else {
Map<String, Object> updateMap = Maps.newHashMapWithExpectedSize(1);
updateMap.put("set", pd.get(key));
document.setField(key, updateMap);
}
}
return document;
}
private List<SolrInputDocument> getUpdateDocuments(List<PageData> documents) {
List<SolrInputDocument> datas = Lists.newArrayList();
for (PageData pd : documents) {
SolrInputDocument doc = getUpdateDocument(pd);
datas.add(doc);
}
return datas;
}
/**
* Title: update
*
* @param document
* @throws Exception
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#update(com.jianong.springbootproject.util.PageData)
*/
@Override
public ResultEntity update(PageData document) {
ResultEntity result = new ResultEntity();
SolrInputDocument doc = getUpdateDocument(document);
return execute(doc);
}
/**
* Title: updataBatch
*
* @param documents
* @return
* @see com.jianong.springbootproject.util.indexes.indexing.IndexeWriter#updataBatch(java.util.List)
*/
@Override
public ResultEntity updataBatch(List<PageData> documents) {
ResultEntity result = new ResultEntity();
int count = 0;
if (documents.size() < 20) {
for (PageData document : documents) {
result = update(document);
}
} else {
List<SolrInputDocument> datas = getDocuments(documents);
try {
UpdateResponse response = solr.add(datas);
commit();
} catch (Exception e) {
}
}
return result;
}
/**
* Title: commit
*
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#commit()
*/
@Override
public void commit() {
try {
solr.commit();
} catch (Exception e) {
LOGGER.error(e);
}
}
/**
* Title: close
*
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#close()
*/
@Override
public void close() {
try {
commit();
solr.close();
} catch (Exception e) {
LOGGER.error(e);
}
}
/**
* Title: detory
*
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#detory()
*/
@Override
public void detory() {
commit();
close();
}
}
- 子类实现抽象类中未实现的接口SolrIndexWriter
public class SolrIndexWriter extends AbstractSolrIndexWriter implements IndexeWriter {
private static final Logger LOGGER = Logger.getLogger(SolrIndexWriter.class);
/**
* Title: delete
*
* @param ids
* @throws Exception
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#delete(java.util.List)
*/
@Override
public ResultEntity delete(List<String> ids) {
return null;
}
/**
* Title: deleteAll
*
* @throws Exception
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#deleteAll()
*/
@Override
public void deleteAll() throws Exception {
UpdateResponse response = solr.deleteByQuery("*:*");
int responseTime = response.getQTime();
solr.commit();
}
/**
* Title: createIndex
*
* @param beginTime
* @throws Exception
* @see com.jianong.springbootproject.util.indexes.IndexeWriter#createIndex(java.lang.String)
*/
@Override
public void createIndex(String beginTime) {
}
}
4.创建solr查询和操作索引的工厂,供外界调用使用SolrManager
public final class SolrManager {
@Resource(name = "solrIndexSearch")
private ISolrIndexSearch solrIndexSearch;
@Resource(name = "solrIndexWriter")
private IndexeWriter indexeWriter;
public SolrQuery getQuery() {
return solrIndexSearch.getQuery();
}
public ResultEntity search(String id) {
return solrIndexSearch.search(id);
}
/**
* 删除索引
*
* @param ids
* @throws Exception
*/
public ResultEntity delete(List<String> ids) {
return indexeWriter.delete(ids);
}
public ResultEntity delete(String id) {
return indexeWriter.delete(id);
}
public void deleteAll() throws Exception {
indexeWriter.deleteAll();
}
public ResultEntity update(PageData document) {
return indexeWriter.update(document);
}
public ResultEntity write(List<PageData> document) {
return indexeWriter.write(document);
}
public ResultEntity write(PageData pd) {
return indexeWriter.write(pd);
}
/**
* 创建索引
*
* @throws Exception
* @Title: createIndex
* @Description:
* @return: void
*/
public void createIndex(String beginTime) throws Exception {
}
/**
* 查询
*
* @param page
* @param query
* @param isHight
* @return
* @throws Exception
*/
public ResultEntity search(Page page, SolrQuery query, boolean isHight) throws Exception {
return solrIndexSearch.search(page, query, isHight);
}
}
5.在application.properties中配置solr
solr.url=http://host:port/solr/
solr.collection=collectionname
#是否为集群
solr.cluster=false
solr.timeout=10000
solr.maxconnection=100
solr.queuesize=20
#集群中必须配置zookeeper地址
solr.zookeeper.url=192.168.0.5:2181
6.配置solr,在spring boot启动中,覆盖默认的solrClient配置
public class SolrConfig implements EnvironmentAware {
private static Logger LOGGER = Logger.getLogger(SolrConfig.class);
private boolean solrCluster = false;
private SolrConfigBean config;
@Override
public void setEnvironment(Environment environment) {
config = new SolrConfigBean();
loadProperties(environment);
}
private void loadProperties(Environment env) {
String url = env.getProperty("solr.url");
int maxConnection = Integer.parseInt(env.getProperty("solr.maxconnection"));
String collection = env.getProperty("solr.collection");
int timeout = Integer.parseInt(env.getProperty("solr.timeout"));
boolean solrIsCluster = Boolean.parseBoolean(env.getProperty("solr.cluster"));
if (solrIsCluster) {
String zookeeperUrl = env.getProperty("solr.zookeeper.url");
if (zookeeperUrl.indexOf(",") != -1) {
String[] tmp = zookeeperUrl.split(",");
List<String> zkList = Lists.newArrayList(tmp);
config.setZookeeperUrl(zkList);
} else {
List<String> zkList = Lists.newArrayList(zookeeperUrl);
config.setZookeeperUrl(zkList);
}
}
config.setTimeout(timeout);
config.setUrl(url);
config.setCollection(collection);
config.setMaxConnection(maxConnection);
solrCluster = solrIsCluster;
}
@Bean
public SolrClient solrClient() {
boolean falg = isSolrCluster();
if (falg) {
SolrClient client = new CloudSolrClient.Builder().withZkHost(config.getZookeeperUrl()).build();
((CloudSolrClient) client).setDefaultCollection(config.getCollection());
((CloudSolrClient) client).setParser(new XMLResponseParser());
((CloudSolrClient) client).setRequestWriter(new BinaryRequestWriter());
return client;
} else {
SolrClient solr = new HttpSolrClient.Builder(getSolrUrl()).build();
((HttpSolrClient) solr).setParser(new XMLResponseParser());
((HttpSolrClient) solr).setRequestWriter(new BinaryRequestWriter());
((HttpSolrClient) solr).setConnectionTimeout(config.getTimeout());
((HttpSolrClient) solr).setSoTimeout(100000);
((HttpSolrClient) solr).setDefaultMaxConnectionsPerHost(config.getMaxConnection());
return solr;
}
}
@Bean
public ConcurrentUpdateSolrClient concurrentUpdateSolrClient() {
ConcurrentUpdateSolrClient client =
new ConcurrentUpdateSolrClient.Builder(getSolrUrl())
.withQueueSize(10)
.build();
client.setRequestWriter(new BinaryRequestWriter());
client.setParser(new XMLResponseParser());
return client;
}
public SolrConfigBean getConfig() {
return config;
}
public String getSolrUrl() {
StringBuffer sb = new StringBuffer();
sb.append(config.getUrl()).append(config.getCollection());
return sb.toString();
}
public boolean isSolrCluster() {
return solrCluster;
}
}
网友评论