概念

在非关系型数据库中,我们常常会有表与表的关联查询。例如学生表和成绩表的关联查询就能查出学生的个人信息和成绩信息。
再Elasticsearch中,父子关系文档就类似于表的关联查询。

背景

ES5开始借助父子关系文档实现多表关联查询,核心是一个索引Index可以创建多个type,甚至在未来版本中将会一处创建类型Type。为了继续支持多表关联查询,从ES6开始推出了join类型来支持父子关系文档的创建

问题与实现

假设现在有这样的需求:

  • 一个博客有多篇文章,文章有标题、内容、作者、日期等信息。
  • 同时一篇文章中会有评论,评论有评论的内容、作者、日期等信息

我们需要通过ES来存储博客的文章以及评论信息。此时文章本身就是”父”,评论就是”子”,这类问题也可以通过nested嵌套对象实现,这里我们只介绍join类型

既然父子文档都可以实现表的关联查询,那么它的数据结构就应该是如下样式:

  1. //文章结构
  2. {
  3. "title":"Elasticsearch7.x",
  4. "author":"chris",
  5. "content":"这是一个教程",
  6. "created":1562141626000,
  7. "comments":[]
  8. }
  9. //评论结构
  10. {
  11. "name":"法外狂徒张三",
  12. "content":"写的真菜",
  13. "created":1562141689000
  14. }

通过API创建索引及映射索引结构:

  1. put /article
  2. {
  3. "mappings": {
  4. "properties": {
  5. "title": {
  6. "type":"text",
  7. "analyzer":"ik_smart",
  8. "fields": {
  9. "keyword": {
  10. "type":"keyword",
  11. "ignore_above":256
  12. }
  13. }
  14. },
  15. "author": {
  16. "type":"text",
  17. "analyzer":"ik_smart",
  18. "fields":{
  19. "keyword":{
  20. "type":"keyword",
  21. "ignore_above":256
  22. }
  23. }
  24. },
  25. "content": {
  26. "type":"text",
  27. "analyzer":"ik_smart"
  28. },
  29. "created": {
  30. "type":"date"
  31. },
  32. "comments": {
  33. "type":"join",
  34. "relations":{
  35. "artice
  36. }
  37. }
  38. }
  39. }
  40. }