关于聚合:Elasticsearch-实现-sql-count-distinct-的功能qbit

前言本文对 Elasticsearch 7.17 实用count distinct单字段 "aggs": { "card": { "cardinality": { "field": "type" } }}多字段 "aggs": { "multi_field_cardinality": { "cardinality": { "script": "doc['type'].value + '#' + doc['color'].value" } }}OR // 这个写法比下面的写法效率高很多{"runtime_mappings": { "type_and_color": { "type": "keyword", "script": "emit(doc['type'].value + '#' + doc['color'].value)" }},"aggs": { "type_and_color": { "cardinality": { "field": "type_and_color" } }}}相干浏览Elasticsearch Cardinality aggregation 官网文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/...StackOverflow:Getting cardinality of multiple fields?本文出自 qbit snap

June 14, 2023 · 1 min · jiezi

关于聚合:BFF层聚合查询服务异步改造及治理实践-京东云技术团队

首先感激王晓老师的[接口优化的常见计划实战总结]一文总结,凑巧最近在对持重理财BFF层聚合查问服务优化治理,针对文章内的串行改并行章节进行开展,分享下实践经验,次要波及原同步改异步的过程、全异步化后衍生的问题以及治理方面的思考与改良。 心愿通过分享这些教训,可能对大家的工作有所启发和帮忙。如果有任何问题或倡议,请随时提出。 一、问题背景将不同理财产品(如基金、券商、保险、银行理财等)针对不同投放渠道人群进行个性化商品举荐,每个渠道或人群看到的商品或个性数据又各不相同,为不便渠道疾速对接,由BFF层对立对所有数据进行聚合下发,因而BFF层汇集依赖了大量底层原子服务,所以次要问题是在依赖大量上游接口的场景下保障TP99、以及可用率。 案例:以其中比拟典型的商品举荐接口为例,须要依赖本地商品池缓存、算法举荐服务、商品根底信息服务、持仓查问服务、人群标签服务、券配置服务,可领用券服务、其余数据服务ServN……等等,其中大部分上游原子接口对单次批量查问反对无限,所以极其状况,单个推品接口单次举荐1-n个推品,每个商品如果要绑定10个动静属性,至多须要发动(1~n)*10次io调用。 革新前的流程和问题:流程: 问题: 一是逻辑流程强耦合,很多上下游服务强同步依赖;二是链路较长,其中某个上游服务不稳固时很容易造成整体链路失败。革新后的流程和实现的指标:流程: 指标: 革新指标也很明确,就是对现有逻辑革新,尽可能减少弱依赖比例,一是不便异步提前加载,二是弱依赖代表可摘除,为降级操作奠定根底,缩小因某个链路抖动影响整体链路失败;初步革新后的新问题【【重点解决】】:▪逻辑上解耦比较简单,无非就是前置参数或冗余加载,本次不开展探讨; ▪技术上革新后期异步逻辑次要是采纳@Async("tpXXX")标注,这也是最快捷实现的形式,但也存在以下几个问题,次要是波及治理方面: 随着我的项目和人员一直迭代,造成@Async注解满天飞;不同人员在不相熟其余模块的状况下,无奈界定不同线程池的是否可专用,大多都会采纳申明新的线程池,造成线程池资源泛滥;局部调用场景不合理造成@Async嵌套过多或注解生效问题;降级机制反复代码太多,须要频繁手动申明各种降级开关;短少对立的申请级别的缓存机制,尽管jsf曾经提供了肯定水平的反对;线程池上下文传递问题;短少线程池状态的对立监控报警,无奈观测理论运行过程中的每个线程池状态,可能每次都是拍脑袋觉设置线程池参数。二、整体革新门路切入点:鉴于大部分我的项目都会封装独自的io调用层,比方 com.xx.package.xxx.client,所以以此为切入点进行重点革新治理。最终目标:实现、利用简略,对老代码革新敌对,尽可能升高革新老本; 形象io调用模板,对立io调用层封装标准,标准化io调用须要的加强属性申明并提供默认配置,如所属线程池调配、超时、缓存、熔断、降级等;优化@Async调用,所有io异步操作对立膨胀至io调用层,在模板层实现回调机制,老代码仅继承模板即可实现异步回调;申请级别的缓存实现,默认反对r2m;申请级别的熔断降级反对,在上游故障时使服务实现肯定水平的自治理;线程池集中管理,对上下文主动传递MDC参数提供反对;线程池状态主动可视化监控、报警实现;反对配置核心动静设置。具体实现:1. io调用形象模板模板次要作用是进行标准和加强,目前提供两种模板,默认模板、缓存模板,核心思想就是对io操作波及的大部分行为进行申明,比方以后服务所属线程池分组、申请分组等,由委托组件依照申明的属性进行加强实现,示例如下: 次要是提供代码级别的默认申明,从日常实际看大部分采纳开发时的代码级别的配置即可。 2. 委托代理此委托属于整个执行过程的桥接实现,io封装实现继承形象模板后,由模板创立委托代理实例,次要用于对io封装进行加强实现,比方调用前、调用后、以及调用失败主动调用申明的降级办法等解决。 能够了解为:模板专一申请行为,委托关注对象行为进行组合加强。 3. 执行器选型基于后面的实现目标,缩小自研老本,调研目前已有框架,如 hystrix、sentinel、resilience4j,因为次要目标是冀望反对线程池级别的壁舱模式实现,且hystrix集成度要优于resilience4j,最终选型默认集成hystrix,备选resilience4j, 以此实现线程池的动态创建治理、熔断降级、半连贯重试等机制,HystrixCommander实现如下: 4. hystrix 适配 concrete 动静配置1、继承concrete.PropertiesNotifier, 注册HystrixPropertiesNotifier监听器,缓存配置核心所有以hystrix起始的key配置; 2、实现HystrixDynamicProperties,注册ConcreteHystrixDynamicProperties替换默认实现,最终反对所有的hystrix配置项,具体用法参考hystrix文档。 5. hystrix 线程池上下文传递革新hystrix曾经提供了革新点,次要是对HystrixConcurrencyStrategy#wrapCallable办法重写实现即可,在submit工作前暂存主线程上下文进行传递。 6. hystrix、jsf、spring注册线程池状态多维可视化监控、报警次要依赖以下三个自定义组件,注册一个状态监控处理器,独自启动一个线程,定期(每秒)收集所有实现数据上报模板的实例,通过指定的通道实现状态数据推送,目前默认应用PFinder上报: ThreadPoolMonitorHandler 定义一个线程状态监控处理器,定期执行上报过程;ThreadPoolEndpointMetrics 定义要上报的数据模板,包含利用实例、线程类型(spring、jsf、hystrix……)、类型线程分组、以及线程池的几个外围参数;AbstractThreadPoolMetricsPublisher 定义监控处理器执行上报时依赖的通道(Micrometer、PFinder、UMP……)。例如以下是hystrix的状态收集实现,最终可实现基于机房、分组、实例、线程池类型、名称等不同维度的状态监控: PFinder实际效果:反对不同维度组合查看及报警 7. 提供对立await future工具类因为大部分调用是基于列表模式的异步后果List<Future<T>>、Map<String,Future<T>>,并且hystrix目前暂不反对返回CompletableFuture,不便对立await,提供工具类: 8. 其余小性能1、除了sgm traceId反对,同时内置自定义的traceId实现,次要是解决sgm在子线程内打印traceId须要在控制台手动增加监控办法的问题以及提供对局部无sgm环境的链路Id反对,不便日志跟踪; 2、比方针对jsf调用,基于jsf过滤器实现跨利用级别的前后申请id传递反对; 3、默认减少jsf过滤器实现日志打印,同时反对provider、consume的动静日志打印开关,不便线上随时开关jsf日志,不再须要在client层反复logger.isDebugerEnabled(); 4、代理层主动上报io调用办法、fallback等信息至ump,不便监控报警。 日常应用示例:1. 一个最简略的io调用封装仅减少继承即可反对异步回调,不重写线程池分组时应用默认分组。 2. 一个反对申请级别熔断的io调用封装默认反对的熔断级别是服务级别,老服务仅须要继承原申请参数,实现FallbackRequest接口即可,可避免因为某一个非凡参数引起的整体接口熔断。 ...

June 2, 2023 · 1 min · jiezi

关于聚合:年初五迎财神-一张码如何实现多渠道微信支付宝云闪付收款

大家好,我是小悟 明天是正月初五,天气超级好,也是迎财神的日子,祝大家逆风逆水,财源滚滚,钱兔似锦。 既然要发财,那天然少不了收款咯。如果你是一个商家,必定是想收款的形式越不便越好,但领取渠道有那么多种,也就意味着顾客的领取抉择也是多种。 那总不能把所有的渠道收款码都贴上吧,那会十分的乱,对顾客来说也极其不不便,一个码能解决的事件,就不要搞复杂化了。那这个是怎么实现的呢? 要实现一码多渠道收款其实也不难,毋庸置疑,当初支流的领取形式就是微信和支付宝,而在微信和支付宝申请的商户相同点是都反对余额、银行卡和信用卡领取,不同点是微信反对云闪付领取,支付宝反对花呗领取。所以只有对接了微信和支付宝,那基本上就够用了。 值得一提的是,随着微信领取生态的倒退,当初想实现这样的性能是越来越不便了。借助微信扫一般链接二维码关上小程序的性能,无需判断前端是微信还是支付宝或者其余APP扫码,能够缩小很多工作量。 所以重点来了,咱们都晓得,微信和支付宝依据前端不同而有多种领取形式,比方APP领取,H5领取,小程序领取等。 为了实现更全和更简略的性能,支付宝须要对接H5领取,而微信须要对接的却是小程序领取。说到这里你可能就有疑难了,为啥不都是H5领取或都是小程序领取? 首先对接支付宝H5领取的话,当你应用其余APP比方抖音、快手关上的时候也能够跳转到支付宝实现领取,一劳永逸。再者因为微信小程序领取反对云闪付领取,所以微信对接的是小程序领取。 说到这里不晓得你曾经想到实现思路了吗?是的,前端须要开发一个简略的页面,然而再简略,起码能够输出金额吧。而后简略做下金额正则校验,因为波及到H5和小程序,所以能够应用uniapp编写前端页面部署更不便,也就是说支付宝部署的是H5,微信部署的是小程序。 我写的demo是搞了两个,不要学我哦,怎么不便怎么来,右边是支付宝H5扫出来的样子,左边是微信小程序扫出来的样子。 ![上传中...]() 领取做多了服务端其实也不简单,留神,支付宝对接的是H5领取,微信对接的是小程序领取,简略贴一下代码。须要写回调的话也肯定不要忘了哦。 支付宝H5领取public AjaxResult aliPayH5(PayModel payModel) { payModel.setBody("支付宝H5领取").setSubject("支付宝H5领取"); String outTradeNo = IdUtil.getSnowflake(1,1).nextIdStr(); payModel.setOutTradeNo(outTradeNo).setPassbackParams(outTradeNo); String form = aliPayService.aliPayH5(payModel); if(StringUtils.isNotBlank(form)) { Map<String, Object> result = new HashMap<>(2); result.put("form", form); return AjaxResult.success(result); } return AjaxResult.error("数据筹备异样");}微信小程序领取public AjaxResult jsapiMaPayCommon(JsapiOrderParam param, HttpServletRequest request) { String openId = param.getOpenId(); String remoteAddr = IpUtils.getIpAddr(request); String outTradeNo = IdUtil.getSnowflake(1,1).nextIdStr(); BigDecimal decimal100 = new BigDecimal("100"); BigDecimal orderAmount = new BigDecimal(String.valueOf(param.getAmount())); JsapiParam jsapiParam = new JsapiParam(); jsapiParam.setAppid(wechatProperties.getMaAppId()) .setMchid(wechatProperties.getMchId()) .setDescription("微信小程序领取") .setOut_trade_no(outTradeNo) .setAttach(outTradeNo) .setNotify_url(wechatProperties.getNotifyUrlCommon()); Amount amount = new Amount(); amount.setTotal(decimal100.multiply(orderAmount).intValue()); jsapiParam.setAmount(amount); Payer payer = new Payer(); payer.setOpenid(openId); jsapiParam.setPayer(payer); SceneInfo sceneInfo = new SceneInfo(); sceneInfo.setDevice_id("POS1:12"); sceneInfo.setPayer_client_ip(remoteAddr); jsapiParam.setScene_info(sceneInfo); BaseParam baseParam = new BaseParam(); baseParam.setAppName(wechatProperties.getAppName()) .setMchId(wechatProperties.getMchId()) .setMchSerialNo(wechatProperties.getMchSerialNo()) .setWechatSerialNo(wechatProperties.getWechatSerialNo()) .setMchPrivateKeyPath(wechatProperties.getMchPrivateKeyPath()) .setWechatPubKeyPath(wechatProperties.getWechatPubKeyPath()); JSONObject result = wechatService.jsapiPay(jsapiParam, baseParam); int status = result.getInteger("requestStatus"); if (status == 200) { SortedMap<Object, Object> params = new TreeMap<>(); String timestamp = Long.toString(System.currentTimeMillis() / 1000); String nonceStr = UuidUtils.randomUUID(); String packageParam = "prepay_id=" + result.getString("prepay_id"); String paySign = SignUtils.paySign(wechatProperties.getMaAppId(), timestamp, nonceStr, packageParam, wechatProperties.getMchPrivateKeyPath()); params.put("appId", wechatProperties.getMaAppId()); params.put("timeStamp", timestamp); params.put("paySign", paySign); params.put("signType", "RSA"); params.put("nonceStr", nonceStr); params.put("package", "prepay_id=" + result.getString("prepay_id")); logger.info("params:{}",params); return AjaxResult.success(params); } else { return AjaxResult.error(result.getString("message"), result); }}部署起来后,支付宝根本就这样了,能领取就行,微信还须要配置一些货色。首先,微信商户号后盾,领取形式配置,云闪付须要开启状态。 ...

January 26, 2023 · 1 min · jiezi

关于聚合:Elasticsearch查询及聚合类DSL语句宝典

作者:京东科技 纪海雨 前言随着应用es场景的增多,工作当中防止不了去应用es进行数据的存储,在数据存储到es当中当前就须要应用DSL语句进行数据的查问、聚合等操作,DSL对SE的意义就像SQL对MySQL一样,学会如何编写查问语句决定了前期是否能齐全驾驭ES,所以至关重要,本专题次要是分享罕用的DSL语句,拿来即用。 一、match如果match 查问数字,日期,布尔值或者not_analyzed 的字符串时,会准确匹配搜寻值,不做分词解析;如果match 查问全文本,会对查问词做分词解析,而后搜寻。 比方对keyword 类型的tag 查问,"京东总部"不会分词,必须齐全相等的词才会被搜寻进去 {a "query": { "match": { "content" : { "tag" : "京东总部" } } }}比方"宝马多少马力"会被分词为"宝马 多少 马力", 所有无关"宝马 多少 马力", 那么所有蕴含这三个词中的一个或多个的文档就会被搜寻进去。并且依据lucene的评分机制(TF/IDF)来进行评分 { "query": { "match": { "content" : { "query" : "宝马多少马力" } } }}二、match_phrase如果想要准确匹配所有同时蕴含"宝马 多少 马力"的文档,就要应用 match_phrase 了 { "query": { "match_phrase": { "content" : { "query" : "宝马多少马力" } } }}三、mult_match如果咱们心愿两个字段进行匹配,其中一个字段有这个文档就满足的话,应用multi_match { "query": { "multi_match": { "query" : "我的宝马多少马力", "fields" : ["title", "content"] } }}四、term关键字准确匹配,不分词解析。留神 term 蕴含(contains) 操作,而非 等值(equals)判断。如果文档蕴含full_text 及其他词,也会命中返回。 ...

December 27, 2022 · 2 min · jiezi

关于聚合:一张收款码同时支持微信云闪付支付宝信用卡支付

想必你也有过这样的经验,在门店生产时,看过商家只张贴了一张收款码,用微信或者支付宝扫码都能够领取,同时反对微信、云闪付、支付宝、信用卡领取。 这样不论是对商家还是顾客来说的确都更加方便快捷。商家只须要张贴一张码,而不须要把收款形式的码比方微信、云闪付、支付宝的码都张贴进去。顾客在抉择付款形式时,只须要关怀本人想要用哪个领取形式而不须要思考商家是张贴了哪个渠道的收款码。 作为代码操盘手,天然要本人入手实际一下看能不能实现这样的成果,于是粗粗的写了代码,粗粗的实现了,粗粗的能够近程收款。 这样的收款形式,收的银子是去哪里了?释怀,是到你在微信或者支付宝平台申请的商户号上,能够间接提现到银行卡上。 原理也很简略,就是对接了微信和支付宝的领取接口,不论是用直连商户还是服务商二级商户,原理也都一样。 收银台在手,生意你有。 一张收款码,同时反对微信、云闪付、支付宝、信用卡领取 山水有相逢,来日皆可期,谢谢浏览,咱们再会 我手中的金箍棒,上能通天,下能探海 上一篇:微信领取APIv3版,平台证书可视化下载工具

August 22, 2022 · 1 min · jiezi