1、上问题
2、问题细化注意,类似的问题是业务问题,如果要实际落地分析,需要进一步核实确认当前的数据建模。 本质一句话:数据的建模决定了数据的存储,数据的存储决定了数据的检索实现。 经反复讨论,敲定了当前的简化的数据建模如下: PUT products 两个字段给大家简单解读一下:
如上的建模就和问题描述建立起一一对应的关系了。 用户id为:1111_2222 的用户,购买了 2 个产品:阳光保险-2016 和 太平洋保险-2020。 现在问题转嫁为:查找购买了“阳光保险-2016” 和 “太平洋保险-2020” 的用户? 到了这里,问题基本上无二义,双方理解基本一致。 ps:这也是咱们公司内部沟通拆解问题的思路,由于问题比较简单,不再啰嗦。 3、问题剖析怎么做? 看到这里,大家可以想一下?暂停几秒,再往后看... ... 这时候,脑海里想一下,检索或者聚合能否实现类似需求? 注意:购买了 “阳光保险-2016” 和 “太平洋保险-2020” ,是与的关系。首先想到的是:bool 和 must 结合。 很快啊,答案写在了下面 POST products/_search 但,放到 Kibana里面执行一下,发现怎么返回结果为空? 大意了吗?!再仔细审题..... 恍然大悟,本质错误原因在于:一对一的字段映射关系,怎么能得到两个或者多个都匹配的结果呢? 这才意识到哪里出了问题?!——不是数据检索,而是数据建模! 4、问题解答问题的本质再细化抽象: 这已经不是简单的 Mysql 中的一对一的数据关系,所谓一对一代表 —— 一个用户 id 对应一个产品名。 如下图所示:多个 1 对 1 表示不同的doc。 而是:一对多的数据关系。 为什么?多个一对一是不能解决:查找购买了“阳光保险-2016” 和 “太平洋保险-2020” 的用户的需求的? 那怎么实现呢?几乎没有更好的方法,除了:数据重新建模。 再建模的时候,要以上面的一对多的图示作为依据。 这时候,脑海里要浮现出 ES 支持哪些所谓“多表关联”操作? 至少应该想到:
我们先拿 Array 数组类型试验,提到数组类型,里面要进一步映射出 Elasticsearch 关于数组的定义:
强调一下:根据数组的定义,之前定义的 Mapping 是不需要修改的。 实践一把: POST products/_bulk 如此,一对一的数据建模变成了一对多的数据建模。 验证一把结果是否达到预期呢? POST products/_search 返回结果(仅贴出了 hits 部分): "hits" : [ 很简单的就实现了需求。 注意:Object,nested 等也可以实现,要根据具体业务所需,不再展开讲。 5、再谈数据建模为什么是再谈,是因为我们强调过:干货 | 论Elasticsearch数据建模的重要性。 尤其基础数据源来自关系型数据库(Mysql、Oracle 等)的业务数据,切记不要将数据同步到ES就完事大吉。 同步之前需要讨论:
这里想的越充分,后面越省事! |
|