跨索引查询:
ES的不同索引,索引结构相同的话是可以进行联合查询。如果索引结构不相同,字段名也不相同,无法做联合查询。
通常不建议在es中做类似mysql的跨表join操作。在设计时,应尽可能的使用扁平化文档模型,也就是在插入阶段将跨表查询的结果组成一个json插入到索引中。parent-child能实现部分结果,但是开销很大,最好是将多个表中数组合并成一个json,提交到索引。
数据关联查询的实现方案:
1、应用端数据关联
实现方法:
1、存储时将数据分为独立的两个索引
2、实际业务的时候,分两次请求,然后将数据组合起来,返送给用户,或者前端
适用场景:数据量少的业务场景。
优点:数据量少时,用户体验好。
缺点:数据量大,两次查询耗时肯定会比较长,影响用户体验。
引申场景:关系型数据库和ES 结合,各取所长。将关系型数据库全量同步到 ES 存储,不做冗余存储。
如前所述:ES 擅长的是检索,而 MySQL 才擅长关系管理。所以可以考虑二者结合,使用 ES 多索引建立相同的别名,针对别名检索到对应 ID 后再回 MySQL 查询,业务层面通过关联 ID join 出需要的数据。(我的理解,对于可能涉及到多个表关联的实现,将数据量最大的用es索引数据,然后将余下的数据量少的让mysql实现关联,最后将es数据和mysql的关联数据结合起来,一起返给客户端)
2、宽表冗余存储
宽表冗余存储的典型方案:将要使用join展示给用户的数据,预先使用视图关联起来,然后同步视图数据到es中。这里的视图就是宽表。
适用场景:一对多或者多对多关联。
优点:速度快。因为每个文档都包含了所需的所有信息,当这些信息需要在查询进行匹配时,并不需要进行昂贵的关联操作。
缺点:索引更新或删除数据,应用程序不得不处理宽表的冗余数据;
由于冗余存储,导致某些搜索和聚合操作可能无法按照预期工作。
3、嵌套文档(Nested)存储
嵌套文档的本质也是将两个不同索引的数据,合并到一个索引中。但与方法一不同的是,方法一是一条数据Join一条数据,而嵌套文档中一条数据文档,可能Join了多条数据文档。典型实例如es官网上说的博客+评论,一个博客对应多条评论。博客是单一的数据,包括标题,内容等;但是评论却有多条,包括用户,年纪,性别等。而嵌套文档就是为了处理一对多情况下,关于多的精确查询(这里就是指评论的查询),这里涉及到了es数据的存储方式,可以参考一些说明。
关于嵌套文档,由于是将两个索引文件合并成一个文件,因此在该索引中,如果对任意一个字段发生更改,添加或者删除,均需要更新文件。
使用场景:文档偶尔更新的场合
优点:速度快,因为文档中包含了多有信息
缺点:索引更新或删除数据,需要重新提交文件,覆盖旧的
另外,关于nested类型的所有操作,均需要额外加一个nested关键字
4、父子文档存储
优点:可以单独更新父子文档,但是相对而言查询更慢。
缺点:父子关系结构改变,需要删除所有内容