renderSchemaStep()

in web-console/src/views/load-data-view/load-data-view.tsx [2375:2645]


  renderSchemaStep() {
    const {
      columnFilter,
      schemaQueryState,
      selectedAutoDimension,
      selectedDimensionSpec,
      selectedMetricSpec,
    } = this.state;
    const spec = this.getEffectiveSpec();
    const rollup = Boolean(deepGet(spec, 'spec.dataSchema.granularitySpec.rollup'));
    const somethingSelected = Boolean(
      selectedAutoDimension || selectedDimensionSpec || selectedMetricSpec,
    );
    const forceSegmentSortByTime = getForceSegmentSortByTime(spec);
    const schemaMode = getSchemaMode(spec);
    const arrayMode = getArrayIngestMode(spec);

    let mainFill: JSX.Element | string;
    if (schemaQueryState.isInit()) {
      mainFill = <CenterMessage>Please enter more details for the previous steps</CenterMessage>;
    } else {
      const data = schemaQueryState.getSomeData();
      mainFill = (
        <div className="table-with-control">
          <div className="table-control">
            <ClearableInput
              value={columnFilter}
              onValueChange={columnFilter => this.setState({ columnFilter })}
              placeholder="Search columns"
            />
          </div>
          {data && (
            <SchemaTable
              sampleBundle={data}
              columnFilter={columnFilter}
              selectedAutoDimension={selectedAutoDimension}
              selectedDimensionSpecIndex={selectedDimensionSpec ? selectedDimensionSpec.index : -1}
              selectedMetricSpecIndex={selectedMetricSpec ? selectedMetricSpec.index : -1}
              onAutoDimensionSelect={this.onAutoDimensionSelect}
              onDimensionSelect={this.onDimensionSelect}
              onMetricSelect={this.onMetricSelect}
            />
          )}
          {schemaQueryState.isLoading() && <Loader />}
          {schemaQueryState.error && (
            <CenterMessage>{schemaQueryState.getErrorMessage()}</CenterMessage>
          )}
        </div>
      );
    }

    const schemaToolsMenu = this.renderSchemaToolsMenu();
    return (
      <>
        <div className="main">{mainFill}</div>
        <div className="control">
          <SchemaMessage schemaMode={schemaMode} />
          {!somethingSelected && (
            <>
              <FormGroupWithInfo
                inlineInfo
                info={
                  <PopoverText>
                    <p>
                      When set to true (the default), segments created by the ingestion job are
                      sorted by <Code>{'{__time, dimensions[0], dimensions[1], ...}'}</Code>. When
                      set to false, segments created by the ingestion job are sorted by{' '}
                      <Code>{'{dimensions[0], dimensions[1], ...}'}</Code>. To include{' '}
                      <Code>__time</Code> in the sort order when this parameter is set to{' '}
                      <Code>false</Code>, you must include a dimension named <Code>__time</Code>{' '}
                      with type <Code>long</Code> explicitly in the `dimensions` list.
                    </p>
                    <p>
                      Setting this to `false` is an experimental feature; see
                      <ExternalLink href={`${getLink('DOCS')}/ingestion/partitioning/#sorting`}>
                        Sorting
                      </ExternalLink>{' '}
                      for details.
                    </p>
                  </PopoverText>
                }
              >
                <Switch
                  checked={forceSegmentSortByTime}
                  onChange={() =>
                    this.setState({
                      newForceSegmentSortByTime: !forceSegmentSortByTime,
                    })
                  }
                  label="Force segment sort by time"
                />
              </FormGroupWithInfo>
              <FormGroupWithInfo
                inlineInfo
                info={
                  <PopoverText>
                    <p>
                      Select whether or not you want to set an explicit list of{' '}
                      <ExternalLink
                        href={`${getLink('DOCS')}/ingestion/ingestion-spec#dimensionsspec`}
                      >
                        dimensions
                      </ExternalLink>{' '}
                      and{' '}
                      <ExternalLink href={`${getLink('DOCS')}/querying/aggregations`}>
                        metrics
                      </ExternalLink>
                      . Explicitly setting dimensions and metrics can lead to better compression and
                      performance. If you disable this option, Druid will try to auto-detect fields
                      in your data and treat them as individual columns.
                    </p>
                  </PopoverText>
                }
              >
                <Switch
                  checked={schemaMode === 'fixed'}
                  onChange={() =>
                    this.setState({
                      newSchemaMode: schemaMode === 'fixed' ? 'type-aware-discovery' : 'fixed',
                    })
                  }
                  label="Explicitly specify schema"
                />
              </FormGroupWithInfo>
              {showArrayIngestModeToggle(spec) && (
                <ArrayIngestModeSwitch
                  arrayIngestMode={arrayMode}
                  changeArrayIngestMode={newArrayIngestMode => {
                    this.setState({
                      newArrayIngestMode: newArrayIngestMode,
                    });
                  }}
                />
              )}
              {schemaMode !== 'fixed' && (
                <AutoForm
                  fields={[
                    {
                      name: 'spec.dataSchema.dimensionsSpec.dimensionExclusions',
                      label: 'Dimension exclusions',
                      type: 'string-array',
                      info: (
                        <>
                          Provide a comma separated list of columns (use the column name from the
                          raw data) you do not want Druid to ingest.
                        </>
                      ),
                    },
                  ]}
                  model={spec}
                  onChange={this.updateSpec}
                />
              )}
              <FormGroupWithInfo
                inlineInfo
                info={
                  <PopoverText>
                    <p>
                      If you enable{' '}
                      <ExternalLink href={`${getLink('DOCS')}/tutorials/tutorial-rollup`}>
                        roll-up
                      </ExternalLink>
                      , Druid will try to pre-aggregate data before indexing it to conserve storage.
                      The primary timestamp will be truncated to the specified query granularity,
                      and rows containing the same string field values will be aggregated together.
                    </p>
                    <p>
                      If you enable rollup, you must specify which columns are{' '}
                      <a href={`${getLink('DOCS')}/ingestion/ingestion-spec#dimensionsspec`}>
                        dimensions
                      </a>{' '}
                      (fields you want to group and filter on), and which are{' '}
                      <a href={`${getLink('DOCS')}/querying/aggregations`}>metrics</a> (fields you
                      want to aggregate on).
                    </p>
                  </PopoverText>
                }
              >
                <Switch
                  checked={rollup}
                  onChange={() => this.setState({ newRollup: !rollup })}
                  label="Rollup"
                />
              </FormGroupWithInfo>
              <AutoForm
                fields={[
                  {
                    name: 'spec.dataSchema.granularitySpec.queryGranularity',
                    label: 'Query granularity',
                    type: 'string',
                    suggestions: [
                      'none',
                      'second',
                      'minute',
                      'fifteen_minute',
                      'thirty_minute',
                      'hour',
                      'day',
                      'week',
                      'month',
                      'quarter',
                      'year',
                      'all',
                    ],
                    info: (
                      <>
                        This granularity determines how timestamps will be truncated (not at all, to
                        the minute, hour, day, etc). After data is rolled up, this granularity
                        becomes the minimum granularity you can query data at.
                      </>
                    ),
                  },
                ]}
                model={spec}
                onChange={this.updateSpecPreview}
                onFinalize={this.applyPreviewSpec}
              />
              <FormGroup>
                <Button
                  text="Add dimension"
                  disabled={schemaMode !== 'fixed'}
                  onClick={() => {
                    this.setState({
                      selectedDimensionSpec: {
                        value: {
                          type: 'string',
                        },
                        index: -1,
                      },
                    });
                  }}
                />
              </FormGroup>
              <FormGroup>
                <Button
                  text="Add metric"
                  onClick={() => {
                    this.setState({
                      selectedMetricSpec: {
                        value: {
                          type: 'doubleSum',
                        },
                        index: -1,
                      },
                    });
                  }}
                />
              </FormGroup>
              {schemaToolsMenu && (
                <FormGroup>
                  <Popover content={schemaToolsMenu}>
                    <Button icon={IconNames.BUILD} text="Tools" />
                  </Popover>
                </FormGroup>
              )}
            </>
          )}
          {this.renderAutoDimensionControls()}
          {this.renderDimensionSpecControls()}
          {this.renderMetricSpecControls()}
          {this.renderChangeForceSegmentSortByTime()}
          {this.renderChangeRollupAction()}
          {this.renderChangeSchemaModeAction()}
          {this.renderChangeArrayIngestModeAction()}
        </div>
        {this.renderNextBar({
          disabled: !schemaQueryState.data,
        })}
      </>
    );
  }