diff --git a/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap b/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap index 42920ceffe9..91e767ae121 100644 --- a/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap +++ b/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap @@ -59,6 +59,7 @@ exports[`retention dialog matches snapshot 1`] = ` documentation diff --git a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx index 80a0ec84dde..a9b695b2e4c 100644 --- a/web-console/src/dialogs/retention-dialog/retention-dialog.tsx +++ b/web-console/src/dialogs/retention-dialog/retention-dialog.tsx @@ -21,7 +21,7 @@ import { IconNames } from '@blueprintjs/icons'; import axios from 'axios'; import React from 'react'; -import { RuleEditor } from '../../components'; +import { ExternalLink, RuleEditor } from '../../components'; import { QueryManager } from '../../utils'; import { DRUID_DOCS_VERSION } from '../../variables'; import { SnitchDialog } from '../snitch-dialog/snitch-dialog'; @@ -183,12 +183,11 @@ export class RetentionDialog extends React.PureComponent<

Druid uses rules to determine what data should be retained in the cluster. The rules are evaluated in order from top to bottom. For more information please refer to the{' '} - documentation - + .

{(currentRules || []).map(this.renderRule)} diff --git a/web-console/src/utils/ingestion-spec.tsx b/web-console/src/utils/ingestion-spec.tsx index 8550c88abdc..32053eee681 100644 --- a/web-console/src/utils/ingestion-spec.tsx +++ b/web-console/src/utils/ingestion-spec.tsx @@ -668,6 +668,7 @@ const METRIC_SPEC_FORM_FIELDS: Field[] = [ { name: 'name', type: 'string', + info: <>The metric name as it will appear in Druid., }, { name: 'type', @@ -694,37 +695,24 @@ const METRIC_SPEC_FORM_FIELDS: Field[] = [ group: 'last', suggestions: ['longLast', 'doubleLast', 'floatLast'], }, - 'cardinality', + 'thetaSketch', + { + group: 'HLLSketch', + suggestions: ['HLLSketchBuild', 'HLLSketchMerge'], + }, + 'quantilesDoublesSketch', + 'momentSketch', + 'fixedBucketsHistogram', 'hyperUnique', 'filtered', ], + info: <>The aggregation function to apply., }, { name: 'fieldName', type: 'string', - defined: m => { - return [ - 'longSum', - 'doubleSum', - 'floatSum', - 'longMin', - 'doubleMin', - 'floatMin', - 'longMax', - 'doubleMax', - 'floatMax', - 'longFirst', - 'doubleFirst', - 'floatFirst', - 'stringFirst', - 'longLast', - 'doubleLast', - 'floatLast', - 'stringLast', - 'cardinality', - 'hyperUnique', - ].includes(m.type); - }, + defined: m => m.type !== 'filtered', + info: <>The column name for the aggregator to operate on., }, { name: 'maxStringBytes', @@ -742,21 +730,196 @@ const METRIC_SPEC_FORM_FIELDS: Field[] = [ return ['stringFirst', 'stringLast'].includes(m.type); }, }, + // filtered { name: 'filter', type: 'json', - defined: m => { - return m.type === 'filtered'; - }, + defined: m => m.type === 'filtered', }, { name: 'aggregator', type: 'json', - defined: m => { - return m.type === 'filtered'; - }, + defined: m => m.type === 'filtered', + }, + // thetaSketch + { + name: 'size', + type: 'number', + defined: m => m.type === 'thetaSketch', + defaultValue: 16384, + info: ( + <> +

+ Must be a power of 2. Internally, size refers to the maximum number of entries sketch + object will retain. Higher size means higher accuracy but more space to store sketches. + Note that after you index with a particular size, druid will persist sketch in segments + and you will use size greater or equal to that at query time. +

+

+ See the{' '} + + DataSketches site + {' '} + for details. +

+

In general, We recommend just sticking to default size.

+ + ), + }, + { + name: 'isInputThetaSketch', + type: 'boolean', + defined: m => m.type === 'thetaSketch', + defaultValue: false, + info: ( + <> + This should only be used at indexing time if your input data contains theta sketch objects. + This would be the case if you use datasketches library outside of Druid, say with Pig/Hive, + to produce the data that you are ingesting into Druid + + ), + }, + // HLLSketchBuild & HLLSketchMerge + { + name: 'lgK', + type: 'number', + defined: m => m.type === 'HLLSketchBuild' || m.type === 'HLLSketchMerge', + defaultValue: 12, + info: ( + <> +

+ log2 of K that is the number of buckets in the sketch, parameter that controls the size + and the accuracy. +

+

Must be between 4 to 21 inclusively.

+ + ), + }, + { + name: 'tgtHllType', + type: 'string', + defined: m => m.type === 'HLLSketchBuild' || m.type === 'HLLSketchMerge', + defaultValue: 'HLL_4', + suggestions: ['HLL_4', 'HLL_6', 'HLL_8'], + info: ( + <> + The type of the target HLL sketch. Must be HLL_4, HLL_6, or{' '} + HLL_8. + + ), + }, + // quantilesDoublesSketch + { + name: 'k', + type: 'number', + defined: m => m.type === 'quantilesDoublesSketch', + defaultValue: 128, + info: ( + <> +

+ Parameter that determines the accuracy and size of the sketch. Higher k means higher + accuracy but more space to store sketches. +

+

+ Must be a power of 2 from 2 to 32768. See the{' '} + + Quantiles Accuracy + {' '} + for details. +

+ + ), + }, + // momentSketch + { + name: 'k', + type: 'number', + defined: m => m.type === 'momentSketch', + required: true, + info: ( + <> + Parameter that determines the accuracy and size of the sketch. Higher k means higher + accuracy but more space to store sketches. Usable range is generally [3,15] + + ), + }, + { + name: 'compress', + type: 'boolean', + defined: m => m.type === 'momentSketch', + defaultValue: true, + info: ( + <> + Flag for whether the aggregator compresses numeric values using arcsinh. Can improve + robustness to skewed and long-tailed distributions, but reduces accuracy slightly on more + uniform distributions. + + ), + }, + // fixedBucketsHistogram + { + name: 'lowerLimit', + type: 'number', + defined: m => m.type === 'fixedBucketsHistogram', + required: true, + info: <>Lower limit of the histogram., + }, + { + name: 'upperLimit', + type: 'number', + defined: m => m.type === 'fixedBucketsHistogram', + required: true, + info: <>Upper limit of the histogram., + }, + { + name: 'numBuckets', + type: 'number', + defined: m => m.type === 'fixedBucketsHistogram', + defaultValue: 10, + required: true, + info: ( + <> + Number of buckets for the histogram. The range [lowerLimit, upperLimit] will be + divided into numBuckets intervals of equal size. + + ), + }, + { + name: 'outlierHandlingMode', + type: 'string', + defined: m => m.type === 'fixedBucketsHistogram', + required: true, + suggestions: ['ignore', 'overflow', 'clip'], + info: ( + <> +

+ Specifies how values outside of [lowerLimit, upperLimit] will be handled. +

+

+ Supported modes are ignore, overflow, and clip. See + + outlier handling modes + {' '} + for more details. +

+ + ), + }, + // hyperUnique + { + name: 'isInputHyperUnique', + type: 'boolean', + defined: m => m.type === 'hyperUnique', + defaultValue: false, + info: ( + <> + This can be set to true to index precomputed HLL (Base64 encoded output from druid-hll is + expected). + + ), }, - // ToDo: fill in approximates ]; export function getMetricSpecFormFields() { diff --git a/web-console/src/views/load-data-view/load-data-view.scss b/web-console/src/views/load-data-view/load-data-view.scss index 6244034c96a..3d972c3b634 100644 --- a/web-console/src/views/load-data-view/load-data-view.scss +++ b/web-console/src/views/load-data-view/load-data-view.scss @@ -88,7 +88,7 @@ bottom: 0; left: 0; content: ''; - border: 2px solid #008adc; + border: 2px solid #48aff0; border-radius: 2px; } @@ -195,7 +195,7 @@ left: 0; right: 0; content: ''; - border: 2px solid #008adc; + border: 2px solid #ff5d10; border-radius: 2px; } diff --git a/web-console/src/views/load-data-view/load-data-view.tsx b/web-console/src/views/load-data-view/load-data-view.tsx index c7a16ee5506..e471c048e5d 100644 --- a/web-console/src/views/load-data-view/load-data-view.tsx +++ b/web-console/src/views/load-data-view/load-data-view.tsx @@ -2444,29 +2444,47 @@ export class LoadDataView extends React.PureComponent { + const specWithoutDimension = deepDelete( + spec, + `dataSchema.parser.parseSpec.dimensionsSpec.dimensions.${selectedDimensionSpecIndex}`, + ); + + const specWithMetric = deepSet(specWithoutDimension, `dataSchema.metricsSpec.[append]`, { + name: `${prefix}_${selectedDimensionSpec.name}`, + type, + fieldName: selectedDimensionSpec.name, + }); + + this.updateSpec(specWithMetric); + close(); + }; + const convertToMetricMenu = ( + convertToMetric('longSum', 'sum')} + /> + convertToMetric('doubleSum', 'sum')} + /> + convertToMetric('thetaSketch', 'theta')} + /> + convertToMetric('HLLSketchBuild', 'hll')} + /> + convertToMetric('quantilesDoublesSketch', 'quantiles_doubles')} + /> { - const specWithoutDimension = deepDelete( - spec, - `dataSchema.parser.parseSpec.dimensionsSpec.dimensions.${selectedDimensionSpecIndex}`, - ); - - const specWithMetric = deepSet( - specWithoutDimension, - `dataSchema.metricsSpec.[append]`, - { - name: `unique_${selectedDimensionSpec.name}`, - type: 'hyperUnique', - fieldName: selectedDimensionSpec.name, - }, - ); - - this.updateSpec(specWithMetric); - close(); - }} + onClick={() => convertToMetric('hyperUnique', 'unique')} /> ); @@ -2483,7 +2501,8 @@ export class LoadDataView extends React.PureComponent