命令查询职责分离模式(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同步数据,可参考博客: 。
当老数据库有大量数据需要导入elasticsearch时,可参考博客:
spring data elasticsearch使用的是transport client,而elasticsearch欧洲杯足彩官网推荐使用rest client。阿里云的elasticsearch使用transport client目前还在存在问题,阿里云推荐使用rest client。
本示例使用的是spring data jest链接elasticsearch,elasticsearch的版本为:5.5.3(目前只有spring boot 2.0以上版本支持)
1.项目构建
- 1.pom依赖如下:
com.github.vanroy
spring-boot-starter-data-jest
3.0.0.release
io.searchbox
jest
5.3.2
- 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; 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 account = (aggregatedpage) 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 account = (aggregatedpage) esparkingorderrepository.search(esquerybuilders.buildyesterdayarrearssumquery(employeeid));
int sum = account.getaggregation("nested", sumaggregation.class).getaggregation("sum", sumaggregation.class).getsum().intvalue();
相关推荐
spring-data-jest, jest的spring data 实现 spring data jest 基于on客户端的elasticsearch的spring data 实现仅在 http ( 例如aws上) 可以访问的情况下使用 spring data 和elasticsearch群集。
本篇文章主要介绍了基于spring data jest的elasticsearch数据统计示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
基于jest rest客户端的elasticsearch的spring data实现 将spring data与仅可通过http访问的elasticsearch集群一起使用(例如在aws上)非常有用。 版本号 spring数据开玩笑 弹簧靴 弹簧数据弹性搜索 笑话 弹性搜索 ...
springboot默认支持两种技术来和elasticsearch进行交互:jest和spring data elasticsearch springboot默认使用spring data elasticsearch模块来进行操作 二、使用 jest是个很流行的elasticsearch客户端工具 使用http...
基于elasticsearch6.8.2进行开发项目描述基于docker环境运行的elasticsearch6.8.2,目前项目中集成了3种与elasticsearch交互的api:使用spring data elasticsearch 3.2.0,需使用es api为6.8.2使用rest high level ...
方法如果传总页数了,es就不用查询总页数,直接通过开始位置到结束位置取数即可
elasticsearch安装部署 head插件使用方法 集成ik分词器 es java api(5种连接方式:节点客户端,传输客户端,restclient,spring data elasticsearch,jest)
elasticsearch java:ransportclient将会在后面的版本中弃用,因此不推荐后续使用;而jest由于是社区维护,所以更新有一定...spring data elasticsearch主要是与spring生态对接,可以在web系统中整合到spring中使用。
connecting to elasticsearch by using spring data 30.6.3. spring data elasticsearch repositories 30.7. cassandra 30.7.1. connecting to cassandra 30.7.2. spring data cassandra repositories 30.8. ...
使用ssm框架(springboot、springsecurity、mybatis)...搭建了linux环境,利用docker安装好了elasticsearch,同时在项目test里测试了elasticsearch,发现springboot data es会报错nodes找不到,而jest却能正常存值和取值
本视频《springboot高级》属于下部,着重介绍springboot的与各大场景的整合使用,内容包括:缓存(整合redis),消息中间件(整合rabbitmq),检索(整合elasticsearch),任务(异步任务,定时任务,邮件任务),...
elasticsearch快速入门 22、尚硅谷-springboot高级-检索-springboot整合jest操作es 23、尚硅谷-springboot高级-检索-整合springdataelasticsearch 24、尚硅谷-springboot高级-任务-异步任务 25、尚硅谷-springboot...