mysql转ElasticSearch的分析 及JAVA API 初探
前言
最近工作中在进行一些技术优化,为了减少对数据库的压力,对于只读操作,在程序与db之间加了一层-ElasticSearch。具体实现是db与es通过bin-log进行同步,保证数据一致性,代码调用es查询数据,与mysql解耦。 
优势:
- 减少与mysql的耦合,查询不依赖于mysql特性。因为当前ElasticSearch的势头如同json一样,轻量、简洁。
 - ElasticSearch扩展性强,可以使用廉价机器平行扩展性能。
 - ElasticSearch对所有字段进行了索引,不用在原mysql表中大量添加索引,减少了数据复杂度。
 
API的个人理解
由于es的java api文档不多,因此参照es官方文档的概念,自己总结了一些api的用法,个人看法,不保证正确。 
ElasticSearch官方文档 
Spring-data-es官方文档
- term 和 terms 是包含操作,而不是相等操作,假如真的需要完全匹配这种行为,最好是通过添加另一个字段来实现。
 - 在 bool 条件中过滤器的顺序对性能有很大的影响。更详细的过滤条件应该被放置在其他过滤器之前,以便在更早的排除更多的文档。
 - 由于es有打分功能,所以api是有配合条件的。withFilter->filter->term,terms,range等一系列不打分的聚合条件。withQuery->must->matchPhrase
 - 查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存。《官方文档.p.133》(因此在进行mysql迁移时,优先使用filter)
 
迁移案例分析
实体
@Document(indexName = "dbName", type = "tableName", shards = 6)
public class UserInfo{
    /**
     * 主键
     */
    @JsonProperty("id")
    private Long id;
    /**
     * 用户编号
     */
    @JsonProperty("user_id")
    private String userId;
    /**
     * 分数
     */
    @JsonProperty("score")
    private String score;
    /**
     * 创建时间
     */
    @JsonProperty("order_time")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @Field(type = FieldType.Date, index = FieldIndex.not_analyzed, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
- queryOne
 
select * from user_info where id = #{id}
public UserInfo getById(String id){
    CriteriaQuery query = new CriteraQuery(Criteria.where("id").is(id));
    UserInfo userInfo = elasticsearchTemplate.queryForObject(query, UserInfo.class);
}
- queryForList(小数据量)
 
select * from user_info where user_id in #{userIdList}
public List<UserInfo> getByUserIdList(List<String> userIdList){
    SearchQuery searchQuery = new NativeSearchQueryBuilder().
    withIndices(EsQueryConstant.obtainIndicesName("dbName","tableName")).
    withFilter(QueryBuilders.termsQuery("user_id",userIdList)).
    return elasticsearchTemplate.queryForList(searchQuery,UserInfo.class);
}
- queryForList(大数据量)
 
select * from user_info where crete_time > #{createTime}
public List<UserInfo> getByUserIdList(Date createTime){
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().
filter(QueryBuilders.rangeQuery("create_time").gt(new DateTime(createTime).toString("yyyy-MM-dd HH:mm:ss")));
    SearchQuery searchQuery = new NativeSearchQueryBuilder().
    withIndices(EsQueryConstant.obtainIndicesName("dbName","tableName")).
    withFilter(boolQueryBuilder ).build();
String scrollId = elasticsearchTemplate.scan(searchQuery, TimeValue.timeValueMinutes(20).getMillis(), false);
        List<UserInfo> result= Lists.newArrayList();
        while (true) {
            Page<UserInfo> userInfoPage = elasticsearchTemplate.scroll(scrollId, TimeValue.timeValueMinutes(20).getMillis(), UserInfo.class);
            List<UserInfo> userInfoContent= orderEsPage.getContent();
            if (CollectionUtils.isEmpty(userInfoContent)) {
                break;
            }
            result.addAll(userInfoContent);
        }
        return result;
}
由于es采用的是分布式存储,所以在数据量大到一定程度的情况下,分页已经变得不可行。比如要拿1000-1010的数据,假设es有6个分片,则每个分片都要拿到1010条数据,总体排序以后取到1000-1010的数据。这样的计算显然是不可能的。所以如果数据量够大,应当使用游标的方式查询数据。虽然指定了页大小,但是这只针对于每一片,实际得到的数据不超过片数*页大小。一直循环,直到所有分片都没有满足条件的数据为止。
- queryForPage
 
select * from user_info where score != #{score} limit #{pageIndex},#{pageSize}
public Page<UserInfo> getByUserIdList(String score,int pageIndex,int pageSize){
BoolQueryBuilder query= QueryBuilders.boolQuery().
mustNot(QueryBuilders.termQuery("score", score);
    SearchQuery searchQuery = new NativeSearchQueryBuilder().
    withIndices(EsQueryConstant.obtainIndicesName("dbName","tableName")).
    withPageable(new PageRequest(pageIndex, pageSize)).
    withFilter(query).build();
    return elasticsearchTemplate.queryForPage(searchQuery,UserInfo.class);
}
后记
本文简单的介绍了mysql转ElasticSearch时的一些场景的案例,API并不难,只是相关资料少,很多功能只能探索前进,以后用到了更深入的功能会继续更新。
mysql转ElasticSearch的分析 及JAVA API 初探的更多相关文章
- Elasticsearch 2.3.3 JAVA api说明文档
		
原文地址:https://www.blog-china.cn/template\documentHtml\1484101683485.html 翻译作者:@青山常在人不老 加入翻译:cdcnsuper ...
 - ElasticSearch 5.0.1 java API操作
		
今天来说下使用ES 5.0.1的API来进行编码. 开始之前,简单说下5.0.1跟之前的几个变化.之前的ES自身是不支持delete-by-query的,也就是通过查询来删除,可以达到批量的效果,是因 ...
 - elasticsearch elk最全java api 搜索 聚合、嵌套查询
		
目录 一. 一般查询... 2 (一) matchAllQuery(client). 2 (二) matchQuery(client);3 (三) multiMatchQuery(client);3 ...
 - ElasticSearch实战系列三: ElasticSearch的JAVA API使用教程
		
前言 在上一篇中介绍了ElasticSearch实战系列二: ElasticSearch的DSL语句使用教程---图文详解,本篇文章就来讲解下 ElasticSearch 6.x官方Java API的 ...
 - mysql转ElasticSearch的案例分析
		
前言 最近工作中在进行一些技术优化,为了减少对数据库的压力,对于只读操作,在程序与db之间加了一层-ElasticSearch.具体实现是db与es通过bin-log进行同步,保证数据一致性,代码调用 ...
 - Elasticsearch java api 基本搜索部分详解
		
文档是结合几个博客整理出来的,内容大部分为转载内容.在使用过程中,对一些疑问点进行了整理与解析. Elasticsearch java api 基本搜索部分详解 ElasticSearch 常用的查询 ...
 - 第08章 ElasticSearch Java API
		
本章内容 使用客户端对象(client object)连接到本地或远程ElasticSearch集群. 逐条或批量索引文档. 更新文档内容. 使用各种ElasticSearch支持的查询方式. 处理E ...
 - Elasticsearch Java API 很全的整理
		
Elasticsearch 的API 分为 REST Client API(http请求形式)以及 transportClient API两种.相比来说transportClient API效率更高, ...
 - Elasticsearch java api操作(二)(Java High Level Rest Client)
		
一.说明: 一.Elasticsearch提供了两个JAVA REST Client版本: 1.java low level rest client: 低级别的rest客户端,通过http与集群交互, ...
 
随机推荐
- [POJ] Bode Plot
			
Description Consider the AC circuit below. We will assume that the circuit is in steady-state. Thus, ...
 - Disconf实践指南:安装篇
			
Disconf是百度开源出来的一款基于Zookeeper的分布式配置管理软件.目前很多公司都在使用,包括滴滴.百度.网易.顺丰等公司.通过简单的界面操作就可以动态修改配置属性,还是很方便的.使用Dis ...
 - 初学者上传文件到github
			
http://blog.csdn.net/steven6977/article/details/10567719 我的github是wzb19960208,怕忘了=.=
 - 1、linux软件包管理
			
linux软件包管理分为两种:RPM包管理和源码包管理,其中RPM包管理又有两种方式:①RPM命令管理,②YUM在线命令管理. RPM包依赖关系: 1.树形依赖 2.环形依赖 (用一条命令同时装来解决 ...
 - 6、数据类型四:sets
			
集合的基本特征:无序,唯一. 一个redis集合最多能存放232-1个集合元素.其强大之处在于它支持集合的“交.差.并”运算,而且能够快速的判断某个给定值是否在集合中. 1.基本命令: SADD ke ...
 - springboot整合最新版dubbo以及dubbo-admin的安装
			
一.安装前准备 由于dubbo被阿里捐献给了apache,这次安装admin时,参考网上的资料,地址还是停留在之前的链接,踩了不少坑,这里记录下. dubbo-admin下载地址: 地址一:https ...
 - python3企业微信群组报警
			
公司提出一个需求需要做一个企业微信的一个消息推送,需要将消息发送到聊天群里详细信息如下. 如何创建应用请阅读我的上篇文章:https://www.cnblogs.com/wangyajunblog/p ...
 - 一张图片优化5k带来的带宽成本及其前端页面的优化方法
			
上周,我参加了公司的一门课程<网站性能优化>,讲师提出了一个问题:一张图片优化后减少5K,1年内可以大概省下多少宽带成本呢?非常好奇,仔细听完讲师分析,计算出来的数据让小伙伴们都惊呆了,仅 ...
 - cdoj32-树上战争(Battle on the tree)                              【记忆化搜索】
			
http://acm.uestc.edu.cn/#/problem/show/32 树上战争(Battle on the tree) Time Limit: 12000/4000MS (Java/Ot ...
 - [hdu4347]The Closest M Points(平衡树式kdtree)
			
解题关键:模板题(结合起来了) #include<iostream> #include<cstdio> #include<cstring> #include< ...