From 783b05d83a0255ce933f212354afeccb358e47fc Mon Sep 17 00:00:00 2001 From: Felipe Wu <felipeshiwu@gmail.com> Date: Thu, 25 Apr 2019 11:13:40 -0300 Subject: [PATCH] [007] Finalizado saida no estilo padrao Signed-off-by: Felipe Wu <felipeshiwu@gmail.com> --- src/adapter/elasticsearch.ts | 93 ++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 21 deletions(-) diff --git a/src/adapter/elasticsearch.ts b/src/adapter/elasticsearch.ts index d3de47bc..8bf3e874 100644 --- a/src/adapter/elasticsearch.ts +++ b/src/adapter/elasticsearch.ts @@ -12,6 +12,17 @@ const elasticsearch = require('elasticsearch'); /** * Adapter which connects with a Elasticsearch database. */ +interface ViewOperation { + opcode?: number; + values?: any[]; + clauses?: any[]; + sort?: any[]; + origin?: boolean; + operation?: object; + id?: string; + name?: string; +} + export class ElasticsearchAdapter extends Adapter { /** Information used to connect with a PostgreSQL database. */ private client: Client; @@ -57,7 +68,6 @@ export class ElasticsearchAdapter extends Adapter { let partialQuery = this.translateAggs(view, 0); Object.assign(query, {aggs: partialQuery}); - //console.log(JSON.stringify(view, null, 2)); return query; } @@ -66,42 +76,32 @@ export class ElasticsearchAdapter extends Adapter { * In other words perform a SELECT query. * @param view - "Location" from all data should be read. * @param cb - Callback function which contains the data read. - * @param cb.error - Error information when the method fails. - * @param cb.result - Data got from view. */ public getDataFromView(view: View, cb: (error: Error, result?: any[]) => void): void { const query = this.getQueryFromView(view); - if (view.clauses.length > 0 || view.dimensions.length == 1) { - this.executeQuery(view.operation.values[0].operation.values[0].name, query, cb); - } else { - this.executeQuery(view.operation.values[0].name, query, cb); - } + let partialView = view.operation; + const index = this.findIndex(partialView); + this.executeQuery(index, view, query, cb); } /** * Asynchronously executes a query and get its result. - * @param query - Query (SQL format) to be executed. + * @param query - Query (Elasticsearch DSL format) to be executed. * @param cb - Callback function which contains the data read. * @param cb.error - Error information when the method fails. * @param cb.result - Query result. */ - private executeQuery(index: string, query: object, cb: (error: Error, result?: any[]) => void): void { + private executeQuery(index: string, view: View, query: object, cb: (error: Error, result?: any[]) => void): void { this.client.search({ index: index.replace(/\"/g, ''), body: query },(err, result) => { - cb(err, [result]); + let displayResult = this.formateResult(view, [result], 0); + cb(err, displayResult); }) } - /** - * Asynchronously insert one register into a given Source. - * @param source - Insertion "location". - * @param cb - Callback function which contains the query result. - * @param cb.error - Error information when the method fails. - * @param cb.result - Query result. - */ public insertIntoSource(source: Source, data: any[], cb: (err: Error, result?: any[]) => void): void { } @@ -122,6 +122,18 @@ export class ElasticsearchAdapter extends Adapter { } } + + /** Elasticsearch, unlike the others adapter, need to find its index to do the query, + * so need to use aliasAsName in the config.yaml and run the recursive function + * below to find the index. + */ + private findIndex(operation: ViewOperation): string{ + if (operation.values[0].origin == true) { + return operation.values[0].name; + } + let index = this.findIndex(operation.values[0].operation); + return index; + } private translateAggs(view: View, numDimensions: number): object { if (numDimensions == view.dimensions.length) { @@ -130,7 +142,7 @@ export class ElasticsearchAdapter extends Adapter { let partialQuery = {}; for (let i=0; i<view.metrics.length; i++) { func = this.getAggregateFunction(view.metrics[i].aggregation); - aggrName = view.metrics[i].name.toLowerCase(); + aggrName = view.metrics[i].name; Object.assign(partialQuery, { [aggrName]: {[func]: {field: view.metrics[i].name}}}); } return partialQuery; @@ -138,7 +150,7 @@ export class ElasticsearchAdapter extends Adapter { let returnedQuery = this.translateAggs(view, numDimensions+1); if (view.dimensions.length > 0) { - let group_by = "group_by_" + view.dimensions[numDimensions].name; + let group_by = view.dimensions[numDimensions].name; let dim = view.dimensions[numDimensions].name; if (view.dimensions[numDimensions].dataType < 3) { dim = dim; @@ -158,11 +170,50 @@ export class ElasticsearchAdapter extends Adapter { Object.assign(aggregation[group_by], {aggs: returnedQuery}); if (numDimensions == view.dimensions.length - 1 && view.sort.length > 0) { - let aggrName = view.sort[0].name.toLowerCase(); + let aggrName = view.sort[0].name; Object.assign(aggregation[group_by].terms, {order: {[aggrName] : "asc"}}); } return aggregation; } } + + private formateResult(view: View, result: any[], numDimensions: number): any[] { + let dimensionsResult = {}; + let back = []; + let resultArray: any[] = []; + if (numDimensions == 0 && view.dimensions.length > 0) { + let firstDim = view.dimensions[0].name; + let resultArray: any[] = []; + for (let i=0; i< result[0].aggregations[firstDim].buckets.length; i++) { + back = this.formateResult(view, [result[0].aggregations[firstDim].buckets[i]], 1); + for (let j=0; j<back.length; j++) { + Object.assign(back[j], {[firstDim]: result[0].aggregations[firstDim].buckets[i].key}); + } + resultArray = resultArray.concat(back); + } + return resultArray; + } + if (numDimensions == view.dimensions.length) { + let metricsResult = {}; + let findPrefix = result[0]; + if (view.dimensions.length == 0) { + findPrefix = result[0].aggregations; + } + for (let i=0; i<view.metrics.length; i++) { + let met = view.metrics[i].name; + Object.assign(metricsResult, {[met]: findPrefix[met].value}); + } + return [metricsResult]; + } + let nDim = view.dimensions[numDimensions].name; + for (let i=0; i< result[0][nDim].buckets.length; i++) { + back = this.formateResult(view, [result[0][nDim].buckets[i]], numDimensions+1); + for (let j=0; j<back.length; j++) { + Object.assign(back[j], {[nDim]: result[0][nDim].buckets[i].key}); + } + resultArray = resultArray.concat(back); + } + return resultArray; + } } -- GitLab