在Elasticsearch这样的分布式系统中执行类似SQL的join连接是代价是比较大的,然而,Elasticsearch却给我们提供了基于水平扩展的两种连接形式 。这句话摘自Elasticsearch官网,从“然而”来看,说明某些场景某些情况下我们还是可以使用的
在关系型数据库中,以MySQL为例,尤其B端类系统且数据量不是特别大的场景,我们经常用到join关键字对有关系的两张或者多张表进行关联查询。但是当数据量达到一定量级时,查询性能就是经常困扰的问题。由于es可以做到数亿量级的秒查(具体由分片数量决定),这时候把数据同步到es是我们可以使用解决方案之一。
那么不禁有疑问问了,由于业务场景的决定,之前必须关联查询的两张表还能做到进行关联吗?
答案是可以的,es也提供了类似于关系型数据库的关联查询,但是它又与关系型数据的关联查询有明显的区别与限制。
如果把关系数据库原有关联的两张表,同步到es后,通常情况下,我们业务开发中会有两种查询诉求的场景
场景1
诉求:展示子表维度的明细数据(包含父表和子表中字段的条件)
方案:对于此种查询诉求,我们可以把原来关联的父子表打成父子表字段混合在一起的大宽表,既能满足查询条件,又有查询性能的保障,也是常用存储方案之一
场景2
诉求:展示父表维度的明细数据(包含父表和子表中字段的条件)
方案:然而,对于此种查询诉求,需要通过子表的条件来查询出父表的明细结果,场景1的宽表存储方案是子表明细数据,而最终我们要的是父表明细数据,显然对于场景1的存储方案是不能满足的。如果非要使用场景1的存储方案,我们还要对宽表结果进行一次groupby或者collapse操作来得到父表结果。
这个时候我们就可以使用es提供的join功能来完成场景2的诉求查询,同时它也满足场景1的诉求查询
由于es属于分布式文档型数据库,数据自然是存在于多个分片之上的。Join字段自然不能像关系型数据库中的join使用。在es中为了保证良好的查询性能,最佳的实践是将数据模型设置为非规范化文档,通过字段冗余构造宽表,即存储在一个索引中。需要满足条件如下:
(1)父子文档(数据)必须存储在同一index中
(2)父子文档(数据)必须存储在同一个分片中,通过关联父文档ID关联
(3)一个index中只能包含一个join字段,但是可以有多个关系
(4)同一个index中,一个父关系可以对应多个子关系,一个子关系只对应一个父关系
当然执行了join查询固然性能会受到一定程度的影响。对于带has_child/has_parent而言,其查询性能会随着指向唯一父文档的匹配子文档的数量增加而降低。本文开篇第一句摘自es官网描述,从ES官方的描述来看join关联查询对性能的损耗是比较大的。
不过,在笔者使用的过程中,在5个分片的前提下,且父表十万量级,子表数据量在千万量级的情况下,关联查询的耗时还是在100ms内完成的,对于B端许多场景还是可以接受的。
若有类似场景,建议我们在使用前,根据分片的多少和预估未来数据量的大小提前做好性能测试,防止以后数量达到一定程度时,性能有明显下降,那个时候再改存储方案得不偿失。
这里以优惠券活动与优惠券明细为例,在一个优惠券活动中可以发放几千万的优惠券,所以券活动与券明细是一对多的关系。
券活动表字段
字段 | 说明 |
---|---|
activity_id | 活动ID |
activity_name | 活动名称 |
券明细表字段
字段 | 说明 |
---|---|
coupon_id | 券ID |
coupon_amount | 券面额 |
activity_id | 外键-活动ID |
join类型的字段主要用来在同一个索引中构建父子关联关系。通过relations定义一组父子关系,每个关系都包含一个父级关系名称和一个或多个子级关系名称
activity_coupon_field是一个关联字段,内部定义了一组join关系,该字段为自命名
type指定关联关系是join,固定写法
relations定义父子关系,activity父类型名称,coupon子类型名称,名称均为自命名
{
"mappings": {
"properties": {
"activity_coupon_field": {
"type": "join",
"relations": {
"activity": "coupon"
}
},
"activity_id": {
"type": "keyword"
},
"activity_name": {
"type": "keyword"
},
"coupon_id": {
"type": "long"
},
"coupon_amount": {
"type": "long"
}
}
}
}
在put父文档数据的时候,我们通常按照某种规则指定文档ID,方便子文档数据变更时易于得到父文档ID。比如这里我们用activity_id的值:activity_100来作为父id
PUT /coupon/_doc/activity_100
{
"activity_id": 100,
"activity_name": "年货节5元促销优惠券",
"activity_coupon_field": {
"name": "activity"
}
}
上边已经指定了父文档ID,而子表中已经包含有activity_id,所以很容易得到父文档ID
put子文档数据时候,必须指定父文档ID,就是父文档中的_id,这样父子数据才建立了关联关系。与此同时还要指定routing字段为父文档ID,这样保证了父子数据在同一分片上。
PUT /coupon/_doc/coupon_12345678?routing=activity_id_100
{
"coupon_id": 12345678,
"coupon_amount": "5",
"activity_id": 100,
"activity_coupon_field": {
"name": "coupon",
"parent": "activity_id_100" //父ID
}
}
根据父文档条件字段查询符合条件的子文档数据
例如:查询包含“年货节”活动字样,且已经被领取过的券
{
"query": {
"bool": {
"must": [{
"parent_type": "activity",
"has_parent": {
"query": {
"bool": {
"must": [{
"term": {
"status": {
"value": 1
}
}
}, {
"wildcard": {
"activity_name": {
"wildcard": "*年货节*"
}
}
}]
}
}
}
}]
}
}
}
根据子文档条件字段符合条件的父文档数据
例如:查询coupon_id=12345678在那个存在于哪个券活动中
{
"query": {
"bool": {
"must": [{
"has_child": {
"type": "coupon",
"query": {
"bool": {
"must": [{
"term": {
"coupon_id": {
"value": 12345678
}
}
}]
}
}
}
}]
}
}
}
参考:Joining queries | Elasticsearch Guide [7.9] | Elastic
以上文中如有不正之处欢迎留言指正
作者:京东零售 李振乾
内容来源:京东云开发者社区
大家好,又见面了,我是全栈君。/* *dianlubuxian.java *Version1.0.0 *Createdon2017年11月30日 *CopyrightReYo.Cn */ packagereyo.sdk.utils.test.dy; /** *<B>创建人:</B>AdministratorReyoAut<BR> *<B>创建时间:</B>2017年11月30日下午4:58:56<BR> * *@authorReYo *@version1.0 */ /** *电路布线问题(动态规划) *@authorLican * */ publicclassdianlubuxian{ publicint[]c;// publicint[][]size;//最大不想交子集 publicint[]net; publicdianlubuxian(int[]cc){ this.c=cc; this.size=newint[cc.length][cc.length];//下标从1开始 this.ne
OpenSSL是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。OpenSSL是Openssl团队的一个开源的能够实现安全套接层(SSLv2/v3)和安全传输层(TLSv1)协议的通用加密库。该产品支持多种加密算法,包括对称密码、哈希算法、安全散列算法等。OpenSSL常常会爆出一些漏洞(图片可点击放大查看)下面介绍CentOS7下rpm包方式升级openssl到安全版本一、CentOS7下rpm包方式升级openssl到安全版本1.1.1n操作步骤如下1、查看并卸载当前openssl版本rpm-aq|grepopenssl rpm-eopenssl-1.0.2k--nodeps 复制(图片可点击放大查看)(图片可点击放大查看)这时需要注意千万别yumremoveopenssl-y,否则依赖openssl的相关包也会被卸载 建议操作前先做好快照,再进行操作!!2、rpm-ivh安装openssl-1.1.1n版本rpm-ivhopenssl-1.1.1n-1.el7.x86_64.rpm--nodeps 复
思路:乱搞就行,就是统计同时存在两个数组里面的元素的个数。#include<bits/stdc++.h> #definemaxn33 usingnamespacestd; inta[maxn],b[maxn]; intvis[maxn]={0}; intmain(){ intn,m; cin>>n>>m; for(inti=1;i<=n;i++){ cin>>a[i]; vis[a[i]]++; } for(inti=1;i<=m;i++){ cin>>b[i]; vis[b[i]]++; } intans=0; for(inti=1;i<=22;i++){ if(vis[i]==2)ans++; } cout<<ans<<endl; return0; }复制 思路:暴力去找就行。#include<bits/stdc++.h> #definemaxn1002 usingnamespacestd; typedeflonglongl
写这类教程的目的是,熟悉Linux基本操作和嵌入式开发流程,希望对你有所帮助.前面我们讲过系统起来后开机LOGO的制作,韦老师第3期讲了如何显示jpeg图片,那么怎么显示bmp图片?这次我们借助libSDL来实现,我们先移植SDL到Ubuntu,体验它的威力后再移植到开发板。一、移植SDL到UbuntuUbuntu:Ubuntu9.10gccversion3.4.51、新建show_bmp_file.c,内容如下:/******************************************************** 文件名称:show_bmp_file.c ****** 程序功能:显示一张bmp图片到屏幕 ****** *********************************************************/ #include<stdio.h> #include"SDL/SDL.h" intmain(intargc,char**argv) { if(argc!=2) { p
一般网站应用中都会应用到三角形,正三角形的写法也有很多,网上一搜一大把。今天我看到一个带有不规则三角形气泡的写法,效果如下:左边部分的矩形比较好实现,通过设置宽高可圆角就可以,但是右边的不规则三角不好用代码实现了。在这里我们用到一个CSS的遮罩属性(CSSMasks):-webkit-mask-image:url(mask.png);CSS遮罩是2008年4月由苹果公司添加到webkit引擎中的。遮罩提供一种基于像素级别的,可以控制元素透明度的能力,类似于png24位或png32位中的alpha透明通道的效果。实现原理:类似于Photoshop中的剪切蒙板,图像是由rgb三个通道以及在每个像素上定义的颜色组成的。但是在他们之上还有第四个通道,alpha通道,通过亮度定义每个像素上的透明度。白色意味着不透明,黑色意味着透明,介于黑白之间的灰色表示半透明。实现原理如下图:代码部分:说完原理我们来看一下代码: 首先我们在body中写一个p标签,class设置为 mask <body> <div class="mask"></div&g
一叶是一款Chrome插件,可以为任意网页开启聊天室,让你随时随地可以聊天 模拟多人聊天的效果(无处不弹幕) 为了演示,我开启了两个Chrome浏览器,两个浏览器各开启一个窗口,GoogleChrome窗口在左侧,GoogleChromeCannary窗口在右侧,左右两个窗口分别登录了不同的用户,效果可以查看下面的gif图 面板功能详解 留言板也很有趣有趣的留言板(各种彩蛋)baidu.com youtube.com google.com bilibili.com zhihu.com github.com 留言方法: 如何保护你的账号?当你下载并启动一叶的插件后,一叶会自动给你分配一个id(这里的id相当于早期的qq号,比如我分配的id就是15519),直接可以进入聊天,如果你把插件卸载再重新安装,就不一定能找回原来的id了,为了避免这种问题,建议你登录后,进入个人资料面板,先记下自己的id,然后修改密码,然后退出登录,用记下的id和修改后的密码登录一下,就稳了~修改密码 确认修改 一些小建议https://api.yiyechat.com/db/comments_wit
在获得数据中心转型的一些成功之后,很多过于心急的企业在实施中希望尽可能多地消除IT数据中心成本。这可能会需要采用多种云服务、实验融合基础架构和软件堆栈,以及采用DevOps友好型技术,例如容器化。这些技术都可以帮助减少日益繁琐的资本支出,并提高敏捷性。尽管如此,在这种数据中心整合的过程中,人们可能会忽略一些重要的事情。云计算和容器的应用规模非常巨大,并且具有更加广阔的前途,但通常他们根本没有通过完整的企业管理和经过考验的安全性,或者正如专家所述,其不能保证服务水平。融合、云计算和容器都是热门技术。它们提供的价值是增加工作负载和基础设施之间的抽象。对于新的分布式的、面向DevOps的世界而言,有更多的抽象是有用的,但它也往往会掩盖对提高IT性能的最终可见性。有很多方法可以衡量性能,而将工作负载响应时间作为衡量最终用户对IT体验的满意程度的重要指标之一。想象一下,图表中的CPU利用率在X轴上从0%线性增加到100%。如果在Y轴上绘制该CPU的平均交互式交易性能,最终会得到一个指数曲线,从合理的服务时间的0%开始,但是在100%的利用率下,将向无穷大发展。(注意:对于数学上的思考,可以使用排
为啥要将ubuntu换成redhat呢,因为接下来想把EDA工具都安装在下面。最后还是因为对显卡驱动不满而重装ubuntu,但这个过程还是学到很多。写在前面,最重要的一点就是U盘的刻录引导,折腾后发现redhat的安装明显比ubuntu要难不少,ubuntu只要将整个iso直接刻录到u盘上就可以直接引导安装了。而redhat需要注意的有,先将images下面的boot.iso提取出来然后刻录到u盘,记得写入syslinux引导,然后将boot.iso里面的vmlinuz,intrid.img两个文件复制到u盘的根目录(用来引导镜像安装),接着将整个dvd.iso复制进u盘放在根目录,这样就不会出现说在u盘,一般说/dev/sdb4找不到diskdriverimage了。首先遇到的第一个问题,本来找不到redhat老版本的下载如4,5(电驴被封了),就下了它的表兄弟版就是centos,我用U盘刻录的是64位的centos6,但我不知道接下来这个问题是不是跟64位有关。安装流程到了分区的时候出现Partitioningerrors:sdamusthaveagptdisklabelhttp:
<?php classNiceSSH{ //SSHHost private$ssh_host='myserver.example.com'; //SSHPort private$ssh_port=22; //SSHServerFingerprint private$ssh_server_fp='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //SSHUsername private$ssh_auth_user='username'; //SSHPublicKeyFile private$ssh_auth_pub='/home/username/.ssh/id_rsa.pub'; //SSHPrivateKeyFile private$ssh_auth_priv='/home/username/.ssh/id_rsa'; //SSHPrivateKeyPassphrase(null==nopassphrase) private$ssh_auth_pass; /
数据持久化(安装MySQL)参考另一篇Docker安装mysql:https://www.cnblogs.com/all-smile/p/16778376.htmlMySQL的数据持久化问题#下载容器 dockerpullmysql:5.7 -d后台运行 -p端口映射 -v挂载数据卷 -e环境配置 --name容器名字 #运行容器 dockerrun-d-p3310:3306-v/home/mysql/conf:/etc/mysql/conf.d-v/home/mysql/data:/var/lib/mysql-eMYSQL_ROOT_PASSWORD=123456--namemysql01mysql:5.7复制https://hub.docker.com/_/mysql官网启动MySQL,设置密码 dockerrun--namesome-mysql-eMYSQL_ROOT_PASSWORD=my-secret-pw-dmysql:tag 启动成功之后,使用客户端连接这里我使用的是SQLyog工具连接MySQL数据库sqlyog连接服务器的3310端口,3310端口映射MySQL容器
平台:Windows764bit,编译器G++(mingw) 工具:DrMemory,项目主页:https://code.google.com/p/drmemory/(可能要FQ,可能会很慢,所以,可以直接按照下面官方主页给出的链接下载,我也放了一份Windows版的在百度网盘,http://pan.baidu.com/s/1qWv2tZm,这个应该肯定可以下载) Thelatestversionscanbedirectlyaccessedhere: Dr.MemoryinstallerforWindows (DrMemory-Windows-1.7.0-5.exe) Dr.Memoryzipfileforportable/localinstallationonWindows (DrMemory-Windows-1.7.0-5.zip) Dr.MemoryforLinux (DrMemory-Linux-1.7.0-5.tar.gz) Dr.MemoryforMac (DrMemory-MacOS-1.7.0-5.tar.gz)
必看参考: http://www.runoob.com/bootstrap/bootstrap-carousel-plugin.html 代码: 1<!DOCTYPEhtml> 2<html> 3<head> 4<title>Bootstrap实例-简单的轮播(Carousel)插件</title> 5<linkhref="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css"rel="stylesheet"> 6<scriptsrc="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> 7<scriptsrc="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></script> 8</head> 9<body> 10 11<divid
三种情况,引出问题: 1) new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会出现野指针情况。 ==>于是出现了引用计数的释放管理机制。 2)对于一个返回对象指针的方法,你若不看文档不看内部代码,你无法知道这个指针需不需要你来释放。同样的对于将一个指针或者对象作为参数给一个方法后,你也无法知道这个方法会不会将你的对象释放掉。 ==> 于是出现了谁拥有谁释放的管理思想。 3)使用上述管理机制和思想后,有些特定情况。比如方法内新建一个对象,然后返回对象时,按照谁拥有谁释放的思想,对象是在方法内部创建的,方法退出前需要释放掉这个对象,但又要在退出时返回这个对象,先返回还是先释放都是不对的。 ==> 于是出现了autorelease。 1、release和retain是配套的,释放管理是通过引用计数的。 每一个CCObject对象
一般说明PW2312是一个高频,同步,整流,降压,开关模式转换器内部功率MOSFET。它提供了一个非常紧凑的解决方案,以实现1.5A的峰值输出电流在广泛的输入电源范围内,具有优良的负载和线路调节PW2312需要最少数量的现成外部组件,可在节省空间的SOT23-6包。 特征⚫宽4V至30V工作输入范围⚫1.2A连续输出电流⚫1.4MHz开关频率⚫短路保护模式⚫内置过流限制⚫内置过电压保护⚫力模式PWM⚫内部软启动⚫200mΩ/150mΩ低RDS(ON)内部功率金氧半电晶体⚫0.8V输出可调⚫不需要肖特基二极管⚫综合内部补偿⚫热关机⚫提供SOT23-6套装⚫-40°C至+85°C温度范围 应用⚫闭路电视摄像机⚫平板电视和显示器⚫电池充电器⚫分布式电力系统 典型应用电路 L1推荐2.2-4.7UH,CIN推荐47-220uF同时并联0.1uF,COUT建议22uF两个并联 引脚分配/说明 绝对最大额定值(注1/2) 注:(1)超过这些额定值可能会损坏设备。(2)不能保证设备在其工作条件外正常工作 功能描述PW2312是一种电流模式降压型DC/D
基本数据类型传参 publicclassTest1{ publicstaticvoidmain(String[]args){ intx=100; inty=x;//x赋值给y是怎么传递的?是把x的值100复制一份给y inti=10; add(i);//把变量i保存的值10.复制1份传给add方法 System.out.println("main域=>"+i); } publicstaticvoidadd(inti){ i++; System.out.println("add域=>"+i); } } 复制 引用数据类型传参 publicclassTest2{ publicstaticvoidmain(String[]args){ Personp=newPerson(); p.age=10; add(p); System.out.println("main方法-->"+p.age); } //创建1个方法 publicstaticvoidadd{ p.age++; System.out.println("add方法的-->"+p.age); } } cla
鉴于之前读的一些文章很容易就忘掉了,故打算花点时间记录下所读的文献。 这几天花了一些时间读了3篇文献: IntersubjectconsistencyofcorticalMEGsignalsduringmovieviewing 这篇文章的目的是通过具有更高分辨率的MEG来扩展2004年发表在自然上的文章中的一些发现(使用fMRI来观察被试间相关性)。 由于血液动力学的一些固有瓶颈(时间分辨率一般低于1Hz),MEG能够记录更高频率的脑电(几十Hz以上),所以更适合去分类短时间的电影片段。 实验的设计是:8个人观看15分钟的黑白电影2次,帧速率:23.98frames/s,然后记录脑磁信号。 数据预处理:signal-spaceseparation(SSS)method,分频段降采样,使用多重线性回归去眼电、心电,PCA降维等。 对预处理的数据使用空间滤波器模型(M-CCA)得到多个成分,如下图即是3个频段的数据在经过M-CCA处理后依次选取前8、5、4个成分计算subject-pair(98个)之间的相位一致性。图中虚线是显著的界限,黑色的长方形块是errorbar(mean+-SD)
1,使用zstack-ctl命令更改IP [root@zstack-1~]#zstack-ctlchange_ip--ip192.168.10.3 Update/etc/hosts,old_ip:192.168.10.3,new_ip:192.168.10.3 Updatecloudbusserverip192.168.10.3in/usr/local/zstack/apache-tomcat/webapps/zstack/WEB-INF/classes/zstack.properties Updatemanagementserverip192.168.10.3in/usr/local/zstack/apache-tomcat/webapps/zstack/WEB-INF/classes/zstack.properties Updateconsoleproxyoverriddenip192.168.10.3in/usr/local/zstack/apache-tomcat/webapps/zstack/WEB-INF/classes/zstack.properties Updatec
https://www.cnblogs.com/dream66/p/10647166.html 前言 RobotFramework作为公司能快速落地实现UI自动化测试的一款框架,同时也非常适合刚入门自动化测试的朋友们去快速学习自动化,笔者计划通过从搭建逐步到完成自动化测试的过程来整体描述它的使用。 复制 RobotFramework环境搭建步骤 RobotFramework是基于Python语言开发的一款框架,搭建步骤如下: 对于RobotFramework熟悉的老手尝鲜新版或python熟悉的朋友看如下简易安装步骤即可(详细截图说明内容适合新入门朋友) 简易安装步骤: 安装python3.7 在dos命令输入pipinstallrobotframework在线安装robotframework 在dos命令输入pipinstallPypubsub==3.3.0在线安装Pypubsub 在dos命令输入pipinstallwxPython==4.0.3在线安装wxPython 在dos命令输入pipinstallrobotframework-ride在线安装robotframework
GraphTheory# DisjointSet## 【模板】并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作。 输入输出格式 输入格式: 第一行包含两个整数N、M,表示共有N个元素和M个操作。 接下来M行,每行包含三个整数Zi、Xi、Yi 当Zi=1时,将Xi与Yi所在的集合合并 当Zi=2时,输出Xi与Yi是否在同一集合内,是的话输出Y;否则话输出N 输出格式: 如上,对于每一个Zi=2的操作,都有一行输出,每行包含一个大写字母,为Y或者N 输入输出样例 输入样例: 47 212 112 212 134 214 123 214 输出样例: N Y N Y 说明 时空限制:1000ms,128M 数据规模: 对于30%的数据,N<=10,M<=20; 对于70%的数据,N<=100,M<=1000; 对于100%的数据,N<=10000,M<=200000。 #include<iostream> #defineMAX_N10000 usingnamespacestd; intn,m,f,x,y,father[