Elasticsearch实现多维数据分析(OLAP)

  • 1、前言

    在线分析系统(OLAP)将已有的数据通过运算公式和转换规则聚合出信息,因此OLAP引擎应该至少能够进行: 

  1. 一个或多个维度对数据进行提取、聚合、合计和预计算;
  2. 一个或多个维度进行逻辑运算、公式等方式的处理; 
  3. 灵活的浏览分析,如一维和多维旋转、交叉表分析、上下钻取等; 

    Elasticsearch(ES)的聚合功能提供了多级分组和统计的能力。聚合类似关系数据库中group by的的功能,在ES中,一次查询中可以使用多维度聚合,这是一个很有用的功能,可以实现如下图所示的功能:

                Elasticsearch实现多维数据分析(OLAP)_第1张图片

        (图一)

  • 2、导入数据到ES

    我们可以使用多种方式将数据导入到ES中,本文中使用的工具是R3,R3默认提供了一个从Excel或CSV导入数据到ES的工具。在读取Excel文件的时候,R3会同时根据SHEET结构自动创建映射到ES的Mapping,格式如下:

{
    rivues: {
        mappings: {
            1njcql: {
                properties: {
                    000fir: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    01sgte: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    080ccu: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    08dma1: {
                        type: "float",
                        store: true
                    },
                    0adfww: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0chxqe: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0dxunn: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0emwon: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0jakw8: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0ketwm: {
                        type: "float",
                        store: true
                    },
                    0kqgph: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0lzrdr: {
                        type: "float",
                        store: true
                    },
                    0mtoal: {
                        type: "float",
                        store: true
                    },
                    0osbwe: {
                        type: "float",
                        store: true
                    },
                    0ra89w: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0vkcgw: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0vpqs9: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    0yrtd9: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    19dyyx: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    1dui0w: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    1ii1lk: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    1pgvv0: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    1r9exi: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    },
                    createtime: {
                        type: "string"
                    },
                    id: {
                        type: "string",
                        index: "not_analyzed",
                        store: true
                    }
                }
            }
        }
    }
}

    字段名称来自于Excel文件中的列标题,对列标题做了Base62编码,编码之后的对应关系部分中文字段内容如下:

                Elasticsearch实现多维数据分析(OLAP)_第2张图片

(图二)

  • 3、建立数据分析模型

    OLAP分析通常包括以下两个方面的内容。

  •     第一,提供一个交互的数据分析的模式。OLAP分析把数据分成维度(Dimension)和度量(Measure或称之为指标)。用户通过选择Dimension(维度)和Measure(度量或指标),可以及时地计算数据在不同Dimension(维度)的组合下的汇总。维度包含层级关系,例如,时间维度,包含年,月,日等。
  •     第二,OLAP分析是一种对数据的处理方式。

    我们可以通过下图所示的结构描述数据分析模型

            Elasticsearch实现多维数据分析(OLAP)_第3张图片

(图三)

 

  • 上图中,维度下包含维度成员,维度成员之间,有层级关系。
  • 4、简单的聚合查询

    为了展现图一所示的查询效果,我们需要在数据模型的基础之上,构建查询语句。

    ES官方的查询语言是DSL,主要分为两类:

  • Query,相当于SQL中的SELECT等;
  • Aggregation,相当于SQL中的GROUP部分,也支持Aggs的内部Filter。

    DSL可以嵌套,表达复杂的查询操作,本文中使用的查询是由R3提供的一个查询构造器,R3提供的查询构造器,使用Hibernate作为开发接口,R3解析Hibernate的DetachedCriteria,并最终将DetachedCriteria翻译成为ES的查询DSL,查询语法如下:

{
  "from" : 0,
  "size" : 0,
  "query" : {
    "bool" : { }
  },
  "aggregations" : {
    "项目类型" : {
      "terms" : {
        "field" : "1ii1lk",
        "size" : 50,
        "order" : {
          "_term" : "asc"
        }
      },
      "aggregations" : {
        "合同时间" : {
          "terms" : {
            "field" : "01sgte",
            "order" : {
              "_term" : "asc"
            }
          },
          "aggregations" : {
            "合同甲方" : {
              "terms" : {
                "field" : "0emwon",
                "order" : {
                  "_term" : "asc"
                }
              },
              "aggregations" : {
                "计划收款金额" : {
                  "sum" : {
                    "field" : "0ketwm",
                    "format" : "0.##"
                  }
                },
                "实际收款金额" : {
                  "sum" : {
                    "field" : "0lzrdr",
                    "format" : "###"
                  }
                },
                "计划付款金额" : {
                  "sum" : {
                    "field" : "0osbwe",
                    "format" : "0.##"
                  }
                },
                "实际付款金额" : {
                  "sum" : {
                    "field" : "0mtoal",
                    "format" : "0.##"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

ES根据查询DSL进行查询,返回如下结果:

 

{
  "took" : 40,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "hits" : {
    "total" : 181,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "项目类型" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [ {
        "key" : "",
        "doc_count" : 1,
        "合同时间" : {
          "doc_count_error_upper_bound" : 0,
          "sum_other_doc_count" : 0,
          "buckets" : [ {
            "key" : "",
            "doc_count" : 1,
            "合同甲方" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [ {
                "key" : "",
                "doc_count" : 1,
                "计划收款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际付款金额" : {
                  "value" : -6228345.0,
                  "value_as_string" : "-6228345"
                },
                "计划付款金额" : {
                  "value" : -6363768.0,
                  "value_as_string" : "-6363768"
                },
                "实际收款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                }
              } ]
            }
          } ]
        }
      }, {
        "key" : "R3",
        "doc_count" : 76,
        "合同时间" : {
          "doc_count_error_upper_bound" : 0,
          "sum_other_doc_count" : 0,
          "buckets" : [ {
            "key" : "2011",
            "doc_count" : 3,
            "合同甲方" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [ {
                "key" : "XXXXXXXXXXXXXXXXXXX",
                "doc_count" : 3,
                "计划收款金额" : {
                  "value" : xxxxx.0,
                  "value_as_string" : "xxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 400000.0,
                  "value_as_string" : "xxxxx"
                }
              } ]
            }
          }, {
            "key" : "2013",
            "doc_count" : 13,
            "合同甲方" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [ {
                "key" : "xxxxx",
                "doc_count" : 1,
                "计划收款金额" : {
                  "value" : 325000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 162500.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 1,
                "计划收款金额" : {
                  "value" : 210000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 210000.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 2,
                "计划收款金额" : {
                  "value" : 440000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 440000.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 2,
                "计划收款金额" : {
                  "value" : 240000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 72000.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 3,
                "计划收款金额" : {
                  "value" : 230000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 184000.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 4,
                "计划收款金额" : {
                  "value" : 580000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 580000.0,
                  "value_as_string" : "xxxxx"
                }
              } ]
            }
          }, {
            "key" : "2014",
            "doc_count" : 30,
            "合同甲方" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [ {
                "key" : "xxxxx",
                "doc_count" : 2,
                "计划收款金额" : {
                  "value" : 380000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 380000.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 7,
                "计划收款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际付款金额" : {
                  "value" : -444905.15625,
                  "value_as_string" : "xxxxx.16"
                },
                "计划付款金额" : {
                  "value" : -444905.1484375,
                  "value_as_string" : "xxxxx.15"
                },
                "实际收款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 10,
                "计划收款金额" : {
                  "value" : 1016720.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 849720.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 3,
                "计划收款金额" : {
                  "value" : 500000.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 450000.0,
                  "value_as_string" : "xxxxx"
                }
              }, {
                "key" : "xxxxx",
                "doc_count" : 8,
                "计划收款金额" : {
                  "value" : 686400.0,
                  "value_as_string" : "xxxxx"
                },
                "实际付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "计划付款金额" : {
                  "value" : 0.0,
                  "value_as_string" : "0"
                },
                "实际收款金额" : {
                  "value" : 686400.0,
                  "value_as_string" : "xxxxx"
                }
              } ]
            }
          }
		}
	}
}

对结果进行格式化,通过表格显示如下图:

               Elasticsearch实现多维数据分析(OLAP)_第4张图片

        (图四)

 

  • 通过图表显示:

              Elasticsearch实现多维数据分析(OLAP)_第5张图片

(图五)

Elasticsearch实现多维数据分析(OLAP)_第6张图片

(图六)

Elasticsearch实现多维数据分析(OLAP)_第7张图片

(图七)


  •  

转载于:https://my.oschina.net/rivues/blog/824066

你可能感兴趣的:(Elasticsearch实现多维数据分析(OLAP))