Elasticsearch multi-index join实践

Elasticsearch 多索引 join 实践

注:本文采用的实现语言是python,用到了python中的第三方库。

作者:aideny

前言

博主近期在开发一个解析引擎,把我们定义的json格式查询语言解析成多种数据源的查询语言,然后可以从服务器上的数据源中查询到结果。就类似数据库理论中视图层的工作吧。

这个解析引擎的工作流程就像下面这样:

image

通过这张图就可以理解博主需要做的工作,就是在后台支持一个实时的查询,用户是无法感知到后台不同数据源之间的查询差异的。

要真正实现一个广义的数据查询引擎,join是一个避不开的问题。后台有一个数据源是ES,由于这是一个实时的解析过程,而且只是一个解析的过程,所以不能更改数据源中已有的数据结构,只能想办法支持怎么去查询它。

博主在这里总结一下,是怎么支持ES的join查询。这里采用的一个方案是比较通用的,不依赖于ES特定版本提供的查询API。因为ES不同版本之间的DSL写法也存在一定的差异。

通用方案

经过调研,支持ES join 有这么一些方法:

  • 完全不join,把关联表的字段融合到一张表里。当然这会造成数据的冗余
  • 录入的时候join:使用 nested documents(nested document和主文档是同segment存储的,对于一个symbol,几千万个quote这样的场景就不适合了)
  • 录入的时候join:使用 siren
  • 查询时join:使用 parent/child (这个是elasticsearch的特性,要求parent/child同shard存在)
  • 查询时join:使用 siren-joins(就是一个在服务端求值的filter,然后把结果发布给每个shard去做二次match)
  • 查询时join:在客户端拼装第二个查询(和siren-joins差不多,但是多了一次客户端到服务器的来回)
  • 在内存中join

由于我需要做的工作是针对已有的“表”进行一个实时的查询,而且线上的ES还有版本差异,有5.x的,有6.x的。所以就不能采用依赖表结构和ES的语法特性了,最后采用的方案是在内存中join。这也是一个通用的方案,不依赖es版本,不依赖于语法特性,只要单表能查,那么就能够join。

具体做法

观察单表查询结果

首先可以观察一下对单索引查询的一个结果,看看它的结构是什么样子。

单索引查询的DSL:

{
  "query": {
    "bool":{
      "must":[
        {
          "range":{
            "data_time":{
              "lte":"2019-11-28T14:07:32.845+0800"
            }
          }
        }
      ]
    }
  },
  "sort":[
    {
      "device":{
        "order":"asc"
      }
    }
  ],

  "aggs":{
    "groupby":{
      "terms":{
        "script": {
          "source":"'p_id:' + doc['p_id'].value + ';' + 'entrance_time:' + doc['entrance_time'].value"
        }
      },
      "aggs":{
        "version__count":{
          "value_count": {
            "field": "version"
          }
        }
      }
    }
  }
}

查询结果:

{
   
  "took": 54,
  "timed_out": false,
  "_shards": {
   
    "total": 5,
    "successful": 5,
    "skipped": 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值