Skip to content

Commit

Permalink
Add merge rollup capabilities with fields
Browse files Browse the repository at this point in the history
  • Loading branch information
sulemanof authored and alexwizp committed Jan 24, 2019
1 parent 70c69da commit d9cc4ec
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const getTimezoneFromRequest = request => {
};

export default class DefaultSearchCapabilities {
constructor(request, batchRequestsSupport, fieldsCapabilities = {}) {
constructor(request, indexPattern, batchRequestsSupport, fieldsCapabilities = {}) {
this.request = request;
this.indexPattern = indexPattern;
this.batchRequestsSupport = batchRequestsSupport;
this.fieldsCapabilities = fieldsCapabilities;

Expand Down Expand Up @@ -61,19 +62,4 @@ export default class DefaultSearchCapabilities {
getSearchInterval(intervalString) {
return this.isTimeIntervalValid(intervalString) ? intervalString : this.defaultTimeInterval;
}

getFieldsByAggregationType(aggregationType) {
const fields = {};

Object.keys(this.fieldsCapabilities).forEach(fieldKey => {
this.fieldsCapabilities[fieldKey].some(aggregation => {
if (aggregation.agg === aggregationType) {
fields[fieldKey] = aggregation;

return true;
}
});
});
return fields;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ export default class DefaultSearchStrategy extends AbstractSearchStrategy {
super(server, callWithRequestFactory, SearchRequest);
}

checkForViability(req) {
checkForViability(req, indexPattern) {
return {
isViable: true,
capabilities: new DefaultSearchCapabilities(req, batchRequestsSupport)
capabilities: new DefaultSearchCapabilities(req, indexPattern, batchRequestsSupport)
};
}
}
69 changes: 69 additions & 0 deletions x-pack/plugins/rollup/server/lib/merge_capabilities_with_fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

// Merge rollup capabilities information with field information

const mergeCapabilitiesWithFields = (rollupIndexCapabilities, fieldsFromFieldCapsApi, previousFields = []) => {
const rollupFields = [...previousFields];
const rollupFieldNames = [];

Object.keys(rollupIndexCapabilities).forEach(agg => {

// Field names of the aggregation
const fields = Object.keys(rollupIndexCapabilities[agg]);

// Default field information
const defaultField = {
name: null,
searchable: true,
aggregatable: true,
readFromDocValues: true,
};

// Date histogram agg only ever has one field defined, let date type overwrite a
// previous type if defined (such as number from max and min aggs).
if(agg === 'date_histogram') {
const timeFieldName = fields[0];
const fieldCapsKey = `${timeFieldName}.${agg}.timestamp`;
const newField = {
...fieldsFromFieldCapsApi[fieldCapsKey],
...defaultField,
name: timeFieldName,
};
const existingField = rollupFields.find(field => field.name === timeFieldName);

if(existingField) {
Object.assign(existingField, newField);
} else {
rollupFieldNames.push(timeFieldName);
rollupFields.push(newField);
}
}
// For all other aggs, filter out ones that have already been added to the field list
// because the same field can be part of multiple aggregations, but end consumption
// doesn't differentiate fields based on their aggregation abilities.
else {
rollupFields.push(
...fields
.filter(field => !rollupFieldNames.includes(field))
.map(field => {
// Expand each field into object format that end consumption expects.
const fieldCapsKey = `${field}.${agg}.value`;
rollupFieldNames.push(field);
return {
...fieldsFromFieldCapsApi[fieldCapsKey],
...defaultField,
name: field,
};
})
);
}
});

return rollupFields;
};

export default mergeCapabilitiesWithFields;
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const intervalMultiple = (userTimeInterval, defaultTimeInterval) => !Boolean(use

export default (DefaultSearchCapabilities) =>
(class RollupSearchCapabilities extends DefaultSearchCapabilities {
constructor(req, batchRequestsSupport, fieldsCapabilities) {
super(req, batchRequestsSupport, fieldsCapabilities);
constructor(req, indexPattern, batchRequestsSupport, fieldsCapabilities) {
super(req, indexPattern, batchRequestsSupport, fieldsCapabilities);

this.init();
}
Expand All @@ -32,9 +32,9 @@ export default (DefaultSearchCapabilities) =>
}

getDateHistogramAggregation() {
const dateHistogramFields = this.getFieldsByAggregationType('date_histogram');
const keys = Object.keys(dateHistogramFields);
const dateHistogramField = this.fieldsCapabilities[this.indexPattern].aggs.date_histogram;

return dateHistogramFields[keys[0]];
// there is also only one valid date_histogram field
return Object.values(dateHistogramField)[0];
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { merge, get } from 'lodash';
import { merge, indexBy } from 'lodash';
import { callWithRequestFactory } from '../call_with_request_factory';
import mergeCapabilitiesWithFields from '../merge_capabilities_with_fields';
import { getCapabilitiesForRollupIndices } from '../map_capabilities';

const ROLLUP_INDEX_CAPABILITIES_METHOD = 'rollup.rollupIndexCapabilities';
const INDEX_PATTERN_SEPARATOR = ',';
const batchRequestsSupport = false;

const getFieldsCapabilities = (rollupData) => {
const rollupIndexKey = Object.keys(rollupData)[0];

return get(rollupData, `${rollupIndexKey}.rollup_jobs.[0].fields`);
};

export default (AbstractSearchStrategy, RollupSearchRequest, RollupSearchCapabilities) =>
(class RollupSearchStrategy extends AbstractSearchStrategy {
name = 'rollup';
Expand Down Expand Up @@ -45,9 +41,9 @@ export default (AbstractSearchStrategy, RollupSearchRequest, RollupSearchCapabil
let capabilities = null;

if (isViable) {
const fieldsCapabilities = getFieldsCapabilities(rollupData);
const fieldsCapabilities = getCapabilitiesForRollupIndices(rollupData);

capabilities = new RollupSearchCapabilities(req, batchRequestsSupport, fieldsCapabilities);
capabilities = new RollupSearchCapabilities(req, indexPattern, batchRequestsSupport, fieldsCapabilities);
}

return {
Expand All @@ -56,13 +52,11 @@ export default (AbstractSearchStrategy, RollupSearchRequest, RollupSearchCapabil
};
}

async getFieldsForWildcard(req, indexPattern/*, capabilities*/) {
async getFieldsForWildcard(req, indexPattern, { fieldsCapabilities }) {
const fields = await super.getFieldsForWildcard(req, indexPattern);
const fieldsFromFieldCapsApi = indexBy(fields, 'name');
const rollupIndexCapabilities = fieldsCapabilities[indexPattern].aggs;

// TODO: write your logic here
// try to reuse x-pack\plugins\rollup\server\routes\api\index_patterns.js
// probably it make sense to move logic related to merging rollup field to separate file

return fields;
return mergeCapabilitiesWithFields(rollupIndexCapabilities, fieldsFromFieldCapsApi);
}
});
58 changes: 3 additions & 55 deletions x-pack/plugins/rollup/server/routes/api/index_patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { wrapEsError, wrapUnknownError } from '../../lib/error_wrappers';
import { licensePreRoutingFactory } from'../../lib/license_pre_routing_factory';
import indexBy from 'lodash/collection/indexBy';
import { getCapabilitiesForRollupIndices } from '../../lib/map_capabilities';
import mergeCapabilitiesWithFields from '../../lib/merge_capabilities_with_fields';
import querystring from 'querystring';

/**
Expand Down Expand Up @@ -57,7 +58,6 @@ export function registerFieldsForWildcardRoute(server) {
const callWithRequest = callWithRequestFactory(server, request);

const rollupFields = [];
const rollupFieldNames = [];
const fieldsFromFieldCapsApi = indexBy(fields, 'name');
const rollupIndexCapabilities = getCapabilitiesForRollupIndices(await callWithRequest('rollup.rollupIndexCapabilities', {
indexPattern: rollupIndex
Expand All @@ -66,62 +66,10 @@ export function registerFieldsForWildcardRoute(server) {
// Keep meta fields
metaFields.forEach(field => fieldsFromFieldCapsApi[field] && rollupFields.push(fieldsFromFieldCapsApi[field]));

// Merge rollup capabilities information with field information
Object.keys(rollupIndexCapabilities).forEach(agg => {

// Field names of the aggregation
const fields = Object.keys(rollupIndexCapabilities[agg]);

// Default field information
const defaultField = {
name: null,
searchable: true,
aggregatable: true,
readFromDocValues: true,
};

// Date histogram agg only ever has one field defined, let date type overwrite a
// previous type if defined (such as number from max and min aggs).
if(agg === 'date_histogram') {
const timeFieldName = fields[0];
const fieldCapsKey = `${timeFieldName}.${agg}.timestamp`;
const newField = {
...fieldsFromFieldCapsApi[fieldCapsKey],
...defaultField,
name: timeFieldName,
};
const existingField = rollupFields.find(field => field.name === timeFieldName);

if(existingField) {
Object.assign(existingField, newField);
} else {
rollupFieldNames.push(timeFieldName);
rollupFields.push(newField);
}
}
// For all other aggs, filter out ones that have already been added to the field list
// because the same field can be part of multiple aggregations, but end consumption
// doesn't differentiate fields based on their aggregation abilities.
else {
rollupFields.push(
...fields
.filter(field => !rollupFieldNames.includes(field))
.map(field => {
// Expand each field into object format that end consumption expects.
const fieldCapsKey = `${field}.${agg}.value`;
rollupFieldNames.push(field);
return {
...fieldsFromFieldCapsApi[fieldCapsKey],
...defaultField,
name: field,
};
})
);
}
});
const mergedRollupFields = mergeCapabilitiesWithFields(rollupIndexCapabilities, fieldsFromFieldCapsApi, rollupFields);

return {
fields: rollupFields
fields: [ ...rollupFields, ...mergedRollupFields ]
};
} catch(err) {
if (isEsError(err)) {
Expand Down

0 comments on commit d9cc4ec

Please sign in to comment.