基于Spring Data Jest的Elasticsearch数据统计示例
命令查询职责分离模式(Command Query Responsibility Segregation,CQRS)从业务上分离修改 (Command,增,删,改,会对系统状态进行修改)和查询(Query,查,不会对系统状态进行修改)的行为。从而使得逻辑更加清晰,便于对不同部分进行针对性的优化。
CQRS有以下几点有点:
1.分工明确,可以负责不同的部分;
2.将业务上的命令和查询的职责分离能够提高系统的性能、可扩展性和安全性。并且在系统的演化中能够保持高度的灵活性,能够防止出现CRUD模式中,对查询或者修改中的某一方进行改动,导致另一方出现问题的情况;
3.逻辑清晰,能够看到系统中的那些行为或者操作导致了系统的状态变化;
4.可以从数据驱动(Data-Driven) 转到任务驱动(Task-Driven)以及事件驱动(Event-Driven)。
因此Command使用数据库,Query使用效率查询效率更高的Elasticsearch。
如何确保数据库和Elasticsearch的数据的一致性?
我们可以使用事件驱动(Event-Driven)即Spring Data的Domain Event同步数据,可参考文章:https://www.geek-share.com/detail/2730720829.html 。
当老数据库有大量数据需要导入Elasticsearch时,可参考文章:https://www.jb51.nethttps://www.geek-share.com/detail/2730456978.html
Spring Data Elasticsearch使用的是transport client,而Elasticsearch官网推荐使用REST client。阿里云的Elasticsearch使用transport client目前还在存在问题,阿里云推荐使用REST client。
本示例使用的是Spring Data Jest链接Elasticsearch(目前只有spring boot2.0以上版本支持),Elasticsearch的版本为:5.5.3
1.项目构建
1.pom依赖如下:
<dependency> <groupId>com.github.vanroy</groupId> <artifactId>spring-boot-starter-data-jest</artifactId> <version>3.0.0.RELEASE</version> </dependency> <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>5.3.2</version> </dependency>
2.配置文件
spring: data: jest: uri: http://127.0.0.1:9200 username: elastic password: changeme
2.构造查询条件
以简单的实体类为例
package com.hfcsbc.esetl.domain; import lombok.Data; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToOne; import java.util.Date; import java.util.List; /** * Create by pengchao on 2018/2/23 */ @Document(indexName = "person", type = "person", shards = 1, replicas = 0, refreshInterval = "-1") @Entity @Data public class Person { @Id private Long id; private String name; @OneToOne @Field(type = FieldType.Nested) private List<Address> address; private Integer number; private Integer status; private Date birthDay; }
package com.hfcsbc.esetl.domain; import lombok.Data; import javax.persistence.Entity; import javax.persistence.Id; /** * Create by pengchao on 2018/2/23 */ @Entity @Data public class Address { @Id private Long id; private String name; private Integer number; }
1.根据多个状态查询(类似于sql的in)
BoolQueryBuilder orderStatusCondition = QueryBuilders.boolQuery() .should(QueryBuilders.termQuery("status", 1)) .should(QueryBuilders.termQuery("status", 2)) .should(QueryBuilders.termQuery("status", 3)) .should(QueryBuilders.termQuery("status", 4)) .should(QueryBuilders.termQuery("status", 5));
2.and链接查询(类似于sql的and)
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); queryBuilder .must(queryBuilder1) .must(queryBuilder2) .must(queryBuilder3);
3.range查询(类似于sql的between .. and ..)
QueryBuilder rangeQuery = QueryBuilders.rangeQuery("birthDay").from(yesterday).to(today);
4.嵌套对象查询
QueryBuilder queryBuilder = QueryBuilders.nestedQuery("nested", QueryBuilders.termQuery("address.id", 100001), ScoreMode.None);
ScoreMode: 定义other join side中score是如何被使用的。如果不关注scoring,我们只需要设置成ScoreMode.None,此种方式会忽略评分因此会更高效和节约内存
3.获取统计数据
1.非嵌套获取数据求和
SumAggregationBuilder sumBuilder = AggregationBuilders.sum("sum").field("number"); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withIndices(QUERY_INDEX) .withTypes(QUERY_TYPE) .withQuery(boolQueryBuilder) .addAggregation(sumBuilder).build(); AggregatedPage<ParkingOrder> account = (AggregatedPage<ParkingOrder>) esParkingOrderRepository.search(EsQueryBuilders.buildYesterdayArrearsSumQuery(employeeId)); int sum = account.getAggregation("sum", SumAggregation.class).getSum().intValue();
2.嵌套数据求和
SumAggregationBuilder sumBuilder = AggregationBuilders.sum("sum").field("adress.num"); AggregationBuilder aggregationBuilder = AggregationBuilders.nested("nested", "adress").subAggregation(sumBuilder); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withIndices(QUERY_INDEX) .withTypes(QUERY_TYPE) .withQuery(boolQueryBuilder) .addAggregation((AbstractAggregationBuilder) aggregationBuilder).build(); AggregatedPage<ParkingOrder> account = (AggregatedPage<ParkingOrder>) esParkingOrderRepository.search(EsQueryBuilders.buildYesterdayArrearsSumQuery(employeeId)); int sum = account.getAggregation("nested", SumAggregation.class).getAggregation("sum", SumAggregation.class).getSum().intValue();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- 基于Spring Batch向Elasticsearch批量导入数据示例
- Spring Boot与Kotlin 整合全文搜索引擎Elasticsearch的示例代码
- Spring Boot整合Elasticsearch实现全文搜索引擎案例解析
- Spring Boot集成ElasticSearch实现搜索引擎的示例
- SpringBoot整合ElasticSearch的示例代码
- 详解spring-boot集成elasticsearch及其简单应用
- 详解spring中使用Elasticsearch的代码实现
- SpringBoot整合ElasticSearch实践
- spring 操作elasticsearch查询使用方法
- 005-spring-data-elasticsearch 3.0.0.0使用【三】-spring-data之Spring数据扩展
- 基于akka和data-sketch技术的实时数据统计服务
- Spring Data MongoDB 使用group和unwind实现对数组数据进行简单统计
- Spring-data-jpa 让数据访问更简单、更优雅
- 基于RGB-D数据的人体检测(People detection in RGB-D data)
- 美国计算机科学与工程专业本科和硕士研究生课程设置特点分析——基于22所美国著名大学统计数据的分析
- spring data redis使用示例
- 按指定上下限区间进行数据统计的示例.sql
- 002-es5.4.3结合spring-data-elasticsearch3.0.0.0使用
- spring data jpa基于Druid连接池的多数据源配置
- Oracle Golden Gate 系列十二 -- GG 数据初始化装载二 基于SCN 的初始化 说明 与 示例
- SpringBoot学习笔记 - 数据访问(Spring Data JPA)
- 基于Spring-Boot和Redis缓存Mysql数据库数据
- 基于随机采样获取训练、测试数据示例(Python)
- CYQ.Data 轻量数据层之路 应用示例二 在线聊天(六)
- 转:浅析基于微软SQL Server 2012 Parallel Data Warehouse的大数据解决方案
- JsonToKotlin(Kotlin开发神器)----Json数据示例直接生成Kotlin Data Class 开发插件
- 数据库操作_连接SQL Server数据库示例;连接ACCESS数据库;连接到 Oracle 数据库示例;SqlCommand 执行SQL命令示例;SqlDataReader 读取数据示例;使用DataAdapter填充数据到DataSet;使用DataTable存储数据库表;将数据库数据填充到 XML 文件;10 使用带输入参数的存储过程;11 使用带输入、输出参数的存储过程示;12 获得数据库中表的数目和名称;13 保存图片到SQL Server数据库示例;14 获得插入记录标识号;Exce
- kafka消费数据存入elasticsearch代码示例
- 【数据架构解读】基于阿里云数加StreamCompute和MaxCompute构建的访问日志统计分析