由于上一遍博客中elasticsearch5.x在linux上分布式安装(多节点) 装的elasticsearch服务比较新,所以将elasticsearch单独做成一个服务运行,需要用的时候用路由转发请求这个服务。
因为elasticsearch版本比较新,所以用到了spring data的里程版本,具体的pom.xml配置和当前这个项目 可以去我github主页下载(https://github.com/lh2420124680/ElasticServer)。
elasticsearch底层用的是lucene,它的搜索速度是非常快的。
在实际的应用中我们有两种部署方案,分别应对不同的业务场景:
①实时保存数据入索引库
当用户保存数据的时候,保存一份到数据库中,当数据库保存成功后,将保存的数据发送到消息队里中(本项目中的消息中间件用的是activeMQ),然后当消息队列监听到有消息发过过来的时候,接受到消息,也就是接受到保存的数据,然后消息监听器执行elasticsearch方法将保存到数据库中的数据同时也保存到对应的索引库中。这种方法对原来的代码侵入少,因为elasticsearch的服务是单独的一个项目。
流程:前端将要插入的数据发送给后台 -> 插入数据库成功 -> 前端执行发送消息队列的方法 -> 发送的数据进入消息队列 -> 消息监听器接收到消息后将数据插入到对应的索引库中。
本方法适用查询实时性并且结构简单的数据。
②每天定时从数据库中将数据同步到索引库中。
这种方法需要用到elastic旗下的一些插件,可以参考本博客中的 elasticsearch与oracle数据库数据同步
本方法适用查询非实时性但结构复杂的数据。
本篇博客主要用的是第一个方法,对spring data中的ElasticsearchTemplate进行了重构,因为ElasticsearchTemplate对于返回值类型依赖实体,并且实体需要用@document注解才能使用,所以本项目中对ElasticsearchTemplate源码进行了重构,将发送参数改为json对象的字符串,返回结果为List
下面会列出一些需要注意的点,需要深入研究的朋友可以去我的githib上下载该项目(https://github.com/lh2420124680/ElasticServer)。
elasticsearch主要的配置文件:com-zlb-elastic.xml
这里我没有用ElasticsearchTemplate,而是用的自定义的elasticObjectTemplate类,让这个类继承ElasticsearchTemplate类,然后重写父类。
然后修改了ElasticsearchTemplate类中的queryForList方法。(父类中的只有查询对象和实体对象两个参数)
本项目v1.0只是对单个插入到索引库的方法进行了重构,后面会慢慢重构ElasticsearchTemplate所有的主要方法。
这里我们需要将传过来的json对象转为object数组,因为父类中会用到
另外我们还需要重构一个类ResultsMapper,用于索引的返回结果对象。
ResultsMapper是用于ElasticsearchTemplate类中返回结果对象的处理类,他返回的List为传输过来的实体泛型,例如当我查询的时候传输后来为Man类,那么他返回就是List
以上就是对源码的重写的一些要点,虽然说的不是很清楚,但是看过几遍ElasticsearchTemplate的源码就会理解。
消息监听器,监听到数据就调用自定义的ElasticObjectTemplate方法去插入到索引库中。
package com.zjy.jms;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zjy.biz.ElasticBiz;
import com.zjy.helper.ElasticObjectTemplate;
import com.zjy.helper.EscapeHelper;
import com.zjy.helper.StringUtils;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class ElasticReceiver implements MessageListener {
private ElasticObjectTemplate elasticObjectTemplate;
public ElasticObjectTemplate getElasticObjectTemplate() {
return elasticObjectTemplate;
}
public void setElasticObjectTemplate(ElasticObjectTemplate elasticObjectTemplate) {
this.elasticObjectTemplate = elasticObjectTemplate;
}
public void onMessage(Message message) {
try {
String msg = ((TextMessage) message).getText();
String data = java.net.URLDecoder.decode(msg, "UTF-8");
String unescape = EscapeHelper.unescape(data);
JSONObject parseObject = JSON.parseObject(unescape);
String dataId = StringUtils.GetGUID();
String indexName = parseObject.getString("indexName");
String typeName = parseObject.getString("typeName");
String entity = parseObject.getString("entity");
IndexQuery indexQuery = new IndexQueryBuilder().withId(dataId).withIndexName(indexName).withType(typeName).withObject(entity).build();
String index = elasticObjectTemplate.index(indexQuery);
System.out.println("indexName:"+indexName + index);
} catch (JMSException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
elasticsearch查询,删除的服务接口。
package com.zjy.service;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.zjy.helper.DataConvertHelper;
import com.zjy.helper.ElasticObjectTemplate;
import com.zjy.helper.EscapeHelper;
import com.zjy.helper.ListResult;
import com.zjy.helper.StringUtils;
@RestController
@RequestMapping(value = "/ElasticService")
public class ElasticService {
@Autowired
private ElasticObjectTemplate elasticObjectTemplate;
/**
* @param request
* @return
*/
@RequestMapping(value = "/queryResource.ashx", method = RequestMethod.GET)
public ListResult
对于前端传输的参数的接口规则可以参考我写的elasticsearch服务api接口文档。(文档地址见图下面的链接)
elasticsearch服务api接口文档下载地址:链接:https://pan.baidu.com/s/1bap8LsjH-GkoT2xJuWZcsw 密码:6tn3
代码地址:https://github.com/lh2420124680/ElasticServer