前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES 中join的使用

ES 中join的使用

作者头像
付威
发布2020-01-21 17:19:58
5.8K0
发布2020-01-21 17:19:58
举报

引出问题

在mysql中,可以使用join来实现表与表之间的数据连接,在es中如何实现这个问题?

相对于mysql来说,es有几个不同的地方

  1. 不支持跨index的join
  2. 一个index只能包含一个类型
  3. 分布式的存储方式,对于数据的搜寻造成障碍

对于上面的几个问题,es的解决方案是**在一个索引下,借助父子关系,实现类似Mysql中多表关联的操作**

定义类型和join索引

代码语言:javascript
复制
PUT myorder
{
 "mappings": {
   "_doc": {
     "properties": {
       "order_join": { 
         "type": "join",
         "relations": {
           "order": "suborder" 
          }
        }
      }
    }
  }
}

定义join关系为order_join,其中order是父文档,suborder是子文档。

代码语言:javascript
复制
put  myorder/_mapping/_doc
{
    "properties": {
    "orderId": {
        "type": "keyword"
    },
    "shortTime": {
        "type": "date"
    },
    "name": {
        "type": "keyword"
    },
    "amount": {
        "type": "double"
    },
    "desc": {
        "type": "text"
    }
  }
}
插入主单数据
代码语言:javascript
复制
PUT myorder/_doc/10001
{
  "shortTime": "2019-01-05",
  "orderId": "10001",
  "name": "user2",
  "amount": 123.09,
  "desc": "其他收入",
  "order_join": "order"
}

order_join定义为order类型

插入子单数据

使用自定义ID用PUT方法

代码语言:javascript
复制
POST myorder/_doc?routing=1
{
  "shortTime": "2019-01-05",
  "orderId": "10001",
  "name": "user2",
  "amount": 12.09,
  "desc": "收入",
  "order_join": {
     "name": "suborder",
     "parent":"10001"
   }
}
代码语言:javascript
复制
POST myorder/_doc?routing=1
{
  "shortTime": "2019-01-05",
  "orderId": "10002",
  "name": "user2",
  "amount": 122.09,
  "desc": "收入",
  "order_join": {
      "name": "suborder",
     "parent":"10001"
   }
}

建立父子关系索引,routing 参数是必须的,因为父子文档必须在同一个分片上

查询主单
代码语言:javascript
复制
GET myorder/_search
{
    "query": {
        "has_child" : {
            "type" : "suborder",
            "query" : {
                "match_all" : {
                    
                }
            }
        }
    }
}
查询子单
代码语言:javascript
复制
GET myorder/_search
{
    "query": {
        "has_parent" : {
            "parent_type" : "order",
            "query" : {
                "match_all" : {
                    
                }
            }
        }
    }
}
聚合查询
  • 主单聚合
代码语言:javascript
复制
GET myorder/_search
{
  "query": {
    "parent_id": {
      "type": "suborder",
      "id": "10001"
    }
  },
  "aggs": {
    "parents12312": {
      "terms": {
        "field": "order_join#order"
      },
      "aggs": {
        "sumAmount": {
          "stats": {
            "field": "amount"
          }
        }
      }
    }
  }
}
  • 子单聚合
代码语言:javascript
复制

  GET myorder/_search
  {
    "size": 0, 
    "aggs": {
      "parent": {
        "children": {
          "type": "suborder"
        },
        "aggs": {
          "sumAmount": {
            "stats": {
              "field": "amount"
            }
          }
        }
      }
    }
  }
 
  • 聚合加筛选:
代码语言:javascript
复制
  GET myorder/_search
  {
        "query": {
          "has_child" : {
              "type" : "suborder",
              "query" : {
                  "match_all" : {
                        
                  }
              }
          }
      },
    "aggs": {
      "parent": {
        "children": {
          "type": "suborder"
        },
        "aggs": {
          "fields": {
            "terms": {
              "field": "orderId"
            },
            "aggs": {
              "sumAmount": {
                "sum": {
                  "field": "amount"
                }
              },
              "having": {
                "bucket_selector": {
                  "buckets_path": {
                    "orderCount": "_count",
                    "sumAmount": "sumAmount"
                  },
                  "script": {
                    "source": "params.sumAmount >= 100 && params.orderCount >=0"
                  }
                }
              }
            }
          }
        }
      }
    }
  } 

定义一对多的索引


一对一的索引模型很难满足日常业务的数据处理,es也支持一对多的join

代码语言:javascript
复制
PUT myorder
{
 "mappings": {
   "_doc": {
     "properties": {
       "order_join": { 
         "type": "join",
         "relations": {
           "order": ["suborder1", "suborder2"],   
           "suborder2":"suborder3"
          }
        }
      }
    }
  }
}

上面的索引的关联的关系如下:

代码语言:javascript
复制
       order
       /   \
 suborder1  suborder2  
              \ 
              suborder3 
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-02-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引出问题
  • 定义类型和join索引
    • 插入主单数据
      • 插入子单数据
        • 查询主单
          • 查询子单
            • 聚合查询
            • 定义一对多的索引
            相关产品与服务
            云数据库 SQL Server
            腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档