"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchHistogramsForFields = void 0; var _get = _interopRequireDefault(require("lodash/get")); var _fieldTypes = require("@kbn/field-types"); var _mlIsPopulatedObject = require("@kbn/ml-is-populated-object"); var _mlStringHash = require("@kbn/ml-string-hash"); var _mlRandomSamplerUtils = require("@kbn/ml-random-sampler-utils"); var _build_sampler_aggregation = require("./build_sampler_aggregation"); var _fetch_agg_intervals = require("./fetch_agg_intervals"); var _get_sampler_aggregations_response_path = require("./get_sampler_aggregations_response_path"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ const MAX_CHART_COLUMNS = 20; function isNumericHistogramField(arg) { return (0, _mlIsPopulatedObject.isPopulatedObject)(arg, ['fieldName', 'type']) && (arg.type === _fieldTypes.KBN_FIELD_TYPES.DATE || arg.type === _fieldTypes.KBN_FIELD_TYPES.NUMBER); } function isNumericHistogramFieldWithColumnStats(arg) { return (0, _mlIsPopulatedObject.isPopulatedObject)(arg, ['fieldName', 'type', 'min', 'max', 'interval']) && (arg.type === _fieldTypes.KBN_FIELD_TYPES.DATE || arg.type === _fieldTypes.KBN_FIELD_TYPES.NUMBER); } function isOrdinalHistogramField(arg) { return (0, _mlIsPopulatedObject.isPopulatedObject)(arg, ['fieldName', 'type']) && (arg.type === _fieldTypes.KBN_FIELD_TYPES.STRING || arg.type === _fieldTypes.KBN_FIELD_TYPES.BOOLEAN); } /** * Fetches data to be used in mini histogram charts. Supports auto-identifying * the histogram interval and min/max values. * * @param client Elasticsearch Client * @param indexPattern index pattern to be queried * @param query Elasticsearch query * @param fields the fields the histograms should be generated for * @param samplerShardSize shard_size parameter of the sampler aggregation * @param runtimeMappings optional runtime mappings * @param randomSamplerProbability optional random sampler probability * @param randomSamplerSeed optional random sampler seed * @returns an array of histogram data for each supplied field */ const fetchHistogramsForFields = async (client, indexPattern, query, fields, samplerShardSize, runtimeMappings, abortSignal, randomSamplerProbability, randomSamplerSeed) => { if (samplerShardSize >= 1 && randomSamplerProbability !== undefined && randomSamplerProbability < 1) { throw new Error('Sampler and Random Sampler cannot be used at the same time.'); } const aggIntervals = { ...(await (0, _fetch_agg_intervals.fetchAggIntervals)(client, indexPattern, query, fields.filter(f => !isNumericHistogramFieldWithColumnStats(f)), samplerShardSize, runtimeMappings, abortSignal, randomSamplerProbability, randomSamplerSeed)), ...fields.filter(isNumericHistogramFieldWithColumnStats).reduce((p, field) => { const { interval, min, max, fieldName } = field; p[(0, _mlStringHash.stringHash)(fieldName)] = { interval, min, max }; return p; }, {}) }; const chartDataAggs = fields.reduce((aggs, field) => { const id = (0, _mlStringHash.stringHash)(field.fieldName); if (isNumericHistogramField(field)) { if (aggIntervals[id] !== undefined) { aggs[`${id}_histogram`] = { histogram: { field: field.fieldName, interval: aggIntervals[id].interval !== 0 ? aggIntervals[id].interval : 1 } }; } } else if (isOrdinalHistogramField(field)) { if (field.type === _fieldTypes.KBN_FIELD_TYPES.STRING) { aggs[`${id}_cardinality`] = { cardinality: { field: field.fieldName } }; } aggs[`${id}_terms`] = { terms: { field: field.fieldName, size: MAX_CHART_COLUMNS } }; } return aggs; }, {}); if (Object.keys(chartDataAggs).length === 0) { return []; } const { wrap, unwrap } = (0, _mlRandomSamplerUtils.createRandomSamplerWrapper)({ probability: randomSamplerProbability !== null && randomSamplerProbability !== void 0 ? randomSamplerProbability : 1, seed: randomSamplerSeed }); const body = await client.search({ index: indexPattern, size: 0, body: { query, aggs: randomSamplerProbability === undefined ? (0, _build_sampler_aggregation.buildSamplerAggregation)(chartDataAggs, samplerShardSize) : wrap(chartDataAggs), size: 0, ...((0, _mlIsPopulatedObject.isPopulatedObject)(runtimeMappings) ? { runtime_mappings: runtimeMappings } : {}) } }, { signal: abortSignal, maxRetries: 0 }); const aggsPath = randomSamplerProbability === undefined ? (0, _get_sampler_aggregations_response_path.getSamplerAggregationsResponsePath)(samplerShardSize) : []; const aggregations = aggsPath.length > 0 ? (0, _get.default)(body.aggregations, aggsPath) : randomSamplerProbability !== undefined && body.aggregations !== undefined ? unwrap(body.aggregations) : body.aggregations; return fields.map(field => { const id = (0, _mlStringHash.stringHash)(field.fieldName); if (isNumericHistogramField(field)) { if (aggIntervals[id] === undefined) { return { type: 'numeric', data: [], interval: 0, stats: [0, 0], id: field.fieldName }; } return { data: aggregations[`${id}_histogram`].buckets, interval: aggIntervals[id].interval, stats: [aggIntervals[id].min, aggIntervals[id].max], type: 'numeric', id: field.fieldName }; } else if (isOrdinalHistogramField(field)) { return { type: field.type === _fieldTypes.KBN_FIELD_TYPES.STRING ? 'ordinal' : 'boolean', cardinality: field.type === _fieldTypes.KBN_FIELD_TYPES.STRING ? aggregations[`${id}_cardinality`].value : 2, data: aggregations[`${id}_terms`].buckets, id: field.fieldName }; } return { type: 'unsupported', id: field.fieldName }; }); }; exports.fetchHistogramsForFields = fetchHistogramsForFields;