diff --git a/src/platform/packages/private/kbn-language-documentation/package.json b/src/platform/packages/private/kbn-language-documentation/package.json index 2c90cc1923394..71036670ea20c 100644 --- a/src/platform/packages/private/kbn-language-documentation/package.json +++ b/src/platform/packages/private/kbn-language-documentation/package.json @@ -7,7 +7,7 @@ "*.scss" ], "scripts": { - "make:docs": "ts-node --transpileOnly scripts/generate_esql_docs.ts", + "make:docs": "./scripts/make_docs.sh", "postmake:docs": "yarn run lint:fix", "lint:fix": "cd ../../../../.. && node ./scripts/eslint --fix ./src/platform/packages/private/kbn-language-documentation/src/sections/generated" } diff --git a/src/platform/packages/private/kbn-language-documentation/scripts/generate_esql_command_docs.ts b/src/platform/packages/private/kbn-language-documentation/scripts/generate_esql_command_docs.ts new file mode 100644 index 0000000000000..b7179e87bed9e --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/scripts/generate_esql_command_docs.ts @@ -0,0 +1,231 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +/* eslint-disable no-console */ + +import * as fs from 'fs'; +import * as path from 'path'; +import { + processingCommandsIntro, + processingCommandsItems, +} from './resources/commands/processing_data'; +import { sourceCommandsIntro, sourceCommandsItems } from './resources/commands/source_data'; +import { CommandDefinition, MultipleLicenseInfo } from '../src/types'; +import { getLicenseInfoForCommand } from '../src/utils/get_license_info'; +import { + DEFINITION_DIR_SUFFIX, + ELASTISEARCH_ESQL_DOCS_BASE_PATH, + OUTPUT_DIR, +} from './scripts.constants'; +import { loadElasticDefinitions } from '../src/utils/load_elastic_definitions'; + +const ELASTIC_COMMAND_DIR_PATH = path.join( + ELASTISEARCH_ESQL_DOCS_BASE_PATH, + DEFINITION_DIR_SUFFIX, + 'commands' +); + +interface CommandItemMetadata { + name: string; + labelDefaultMessage: string; + descriptionDefaultMessage: string; + descriptionOptions?: { + ignoreTag?: boolean; + description?: string; + }; + openLinksInNewTab?: boolean; + preview?: boolean; + license?: MultipleLicenseInfo; +} + +interface CommandSectionMetadata { + labelKey: string; + labelDefaultMessage: string; + descriptionKey: string; + descriptionDefaultMessage: string; + items: CommandItemMetadata[]; + outputFile: string; +} + +const commandsData: CommandSectionMetadata[] = [ + { + ...sourceCommandsIntro, + items: sourceCommandsItems, + outputFile: `${OUTPUT_DIR}/source_commands.tsx`, + }, + { + ...processingCommandsIntro, + items: processingCommandsItems, + outputFile: `${OUTPUT_DIR}/processing_commands.tsx`, + }, +]; + +/** + * This script generates the ESQL inline command documentation files by merging + * the source and processing commands with Elasticsearch definitions. + * + * Step 1: Load the Elasticsearch command definitions from the specified path. + * Step 2: Merge the loaded definitions with the source and processing commands. + * Step 3: Generate separate documentation files for each command type, including the extra information, such as license details. + * Step 4: Write the generated content to the output files in the specified directory. + */ +(function () { + try { + console.log(`Start generating commands documentation`); + + const pathToElasticsearch = process.argv[2]; + if (!pathToElasticsearch) { + throw new Error( + 'No Elasticsearch path provided, generating without license info for testing...' + ); + } + + const esCommandDirPath = path.join(pathToElasticsearch, ELASTIC_COMMAND_DIR_PATH); + const cmdDefinitions = loadElasticDefinitions(esCommandDirPath); + const commands = commandsData.map((cmd) => addDefinitionsToCommands(cmd, cmdDefinitions)); + const docContents = commands.map((cmd) => generateDoc(cmd)); + + // Ensure the output directory exists + if (!fs.existsSync(OUTPUT_DIR)) { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + } + + // Write each generated documentation file + docContents.forEach((content, i) => fs.writeFileSync(`${commands[i].outputFile}`, content)); + console.log(`Sucessfully generated commands documentation files`); + } catch (error) { + console.error(`Error writing documentation files: ${error.message}`); + process.exit(1); + } +})(); + +/** + * Adds Elasticsearch information, such as license details, to commands + */ +function addDefinitionsToCommands( + data: CommandSectionMetadata, + definitions: Map +): CommandSectionMetadata { + return { + ...data, + items: data.items.map((item) => { + const commandDef = definitions.get(item.name); + const licenseInfo = getLicenseInfoForCommand(commandDef); + + if (licenseInfo) { + return { + ...item, + license: licenseInfo, + }; + } + return item; + }), + }; +} + +/** + * Generates the full content for a single command documentation file. + */ +function generateDoc(data: CommandSectionMetadata): string { + return ` +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { Markdown as SharedUXMarkdown } from '@kbn/shared-ux-markdown'; + +const Markdown = (props: Parameters[0]) => ( + +); + +// Do not edit manually... automatically generated by scripts/generate_esql_command_docs.ts + +export const commands = ${generateCommandSectionDoc(data)}; +`; +} + +/** + * Generates a documentation for a specific group of commands. + */ +function generateCommandSectionDoc({ + items, + labelKey, + labelDefaultMessage, + descriptionKey, + descriptionDefaultMessage, +}: CommandSectionMetadata): string { + const commandsContentDoc = items.map((item) => generateCommandItemDoc(item)).join(',\n '); + + return `{ + label: i18n.translate('${labelKey}', { + defaultMessage: '${labelDefaultMessage}', + }), + description: i18n.translate('${descriptionKey}', { + defaultMessage: \`${descriptionDefaultMessage}\`, + }), + items: [ + ${commandsContentDoc} + ], +}`; +} + +/** + * Generates a single command documentation. + */ +function generateCommandItemDoc({ + name, + labelDefaultMessage, + descriptionDefaultMessage, + openLinksInNewTab, + descriptionOptions, + preview, + license, +}: CommandItemMetadata): string { + function generateMarkdownProps(props: { openLinksInNewTab?: boolean }): string { + return props.openLinksInNewTab ? ' openLinksInNewTab={true}' : ''; + } + + function generateDescriptionOptions( + options: { + ignoreTag?: boolean; + description?: string; + } = {} + ) { + const formattedDescriptionOptions = Object.entries(options || {}).map(([key, value]) => + typeof value === 'boolean' + ? `${key}: ${value},` + : `${key}: '${String(value).replace(/'/g, "\\'")}',` + ); + + return formattedDescriptionOptions.length > 0 + ? `,\n ${formattedDescriptionOptions.join('\n')}` + : ''; + } + + // Sample (as a command) use a special suffix to avoid conflict with the same function name + const labelKey = `languageDocumentation.documentationESQL.${ + name === 'sample' ? name + 'Command' : name + }`; + const descriptionKey = `${labelKey}.markdown`; + const previewProp = preview !== undefined ? `\n preview: ${preview},` : ''; + const licenseProp = license ? `\n license: ${JSON.stringify(license)},` : ''; + // replace(/`/g, '\\`') escape backticks for nested template literals in the generated file + const description = descriptionDefaultMessage.replace(/`/g, '\\`'); + + return `{ + label: i18n.translate('${labelKey}', { + defaultMessage: '${labelDefaultMessage}', + }),${previewProp} + description: ( + + ),${licenseProp} +}`; +} diff --git a/src/platform/packages/private/kbn-language-documentation/scripts/generate_esql_docs.ts b/src/platform/packages/private/kbn-language-documentation/scripts/generate_esql_docs.ts index 32500d7afa810..6ed62af4b150c 100644 --- a/src/platform/packages/private/kbn-language-documentation/scripts/generate_esql_docs.ts +++ b/src/platform/packages/private/kbn-language-documentation/scripts/generate_esql_docs.ts @@ -12,13 +12,14 @@ const n = recast.types.namedTypes; import fs from 'fs'; import path from 'path'; import { functions } from '../src/sections/generated/scalar_functions'; -import { getLicenseInfo } from '../src/utils/get_license_info'; -import { FunctionDefinition } from '../src/types'; +import { getLicenseInfoForFunctions } from '../src/utils/get_license_info'; +import { FunctionDefinition, MultipleLicenseInfo } from '../src/types'; +import { loadElasticDefinitions } from '../src/utils/load_elastic_definitions'; interface DocsSectionContent { description: string; preview: boolean; - license: ReturnType | undefined; + license: MultipleLicenseInfo | undefined; } (function () { @@ -87,9 +88,8 @@ function loadFunctionDocs({ // Read the directory const docsFiles = fs.readdirSync(pathToDocs); - const ESFunctionDefinitions = fs - .readdirSync(pathToDefs) - .map((file) => JSON.parse(fs.readFileSync(`${pathToDefs}/${file}`, 'utf-8'))); + const fnDefinitionsMap = loadElasticDefinitions(pathToDefs); + const ESFunctionDefinitions = Array.from(fnDefinitionsMap.values()); const docs = new Map(); @@ -118,20 +118,14 @@ function loadFunctionDocs({ functionDefinition.titleName ? functionDefinition.titleName : baseFunctionName }${functionDefinition.operator ? ` (${functionDefinition.operator})` : ''}`; - // Create a map of function definitions for quick lookup - const fnDefinitionMap: Map = new Map(); - ESFunctionDefinitions.forEach((def) => { - fnDefinitionMap.set(def.name, def); - }); - // Find corresponding function definition for license information - const fnDefinition = fnDefinitionMap.get(baseFunctionName); + const fnDefinition = fnDefinitionsMap.get(baseFunctionName); // Add the function name and content to the map docs.set(functionName, { description: content, preview: functionDefinition.preview, - license: getLicenseInfo(fnDefinition), + license: getLicenseInfoForFunctions(fnDefinition), }); } } diff --git a/src/platform/packages/private/kbn-language-documentation/scripts/make_docs.sh b/src/platform/packages/private/kbn-language-documentation/scripts/make_docs.sh new file mode 100755 index 0000000000000..626d1ef57b253 --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/scripts/make_docs.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Wrapper script to handle path parameter for make:defs +if [ -z "$1" ]; then + echo "Error: Path to Elasticsearch is required" + echo "Usage: $0 /path/to/elasticsearch" + exit 1 +fi + +ELASTICSEARCH_PATH="$1" + +# Run both scripts with the provided path +ts-node --transpileOnly ./scripts/generate_esql_command_docs.ts "$ELASTICSEARCH_PATH" && \ +ts-node --transpileOnly ./scripts/generate_esql_docs.ts "$ELASTICSEARCH_PATH" diff --git a/src/platform/packages/private/kbn-language-documentation/scripts/resources/commands/processing_data.ts b/src/platform/packages/private/kbn-language-documentation/scripts/resources/commands/processing_data.ts new file mode 100644 index 0000000000000..86c2c273aee8e --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/scripts/resources/commands/processing_data.ts @@ -0,0 +1,609 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +// Template data for ESQL command documentation +// The generate_esql_command_docs.ts script will convert this to TSX with React components + +export const processingCommandsIntro = { + labelKey: 'languageDocumentation.documentationESQL.processingCommands', + labelDefaultMessage: 'Processing commands', + descriptionKey: 'languageDocumentation.documentationESQL.processingCommandsDescription', + descriptionDefaultMessage: `Processing commands change an input table by adding, removing, or changing rows and columns. ES|QL supports the following processing commands.`, +}; + +export const processingCommandsItems = [ + { + name: 'change_point', + labelDefaultMessage: 'CHANGE_POINT', + descriptionDefaultMessage: `### CHANGE POINT +\`CHANGE POINT\`detects spikes, dips, and change points in a metric. + +The command adds columns to the table with the change point type and p-value, that indicates how extreme the change point is (lower values indicate greater changes). + +The possible change point types are: + +* \`dip\`: a significant dip occurs at this change point +* \`distribution_change\`: the overall distribution of the values has changed significantly +* \`spike\`: a significant spike occurs at this point +* \`step_change\`: the change indicates a statistically significant step up or down in value distribution +* \`trend_change\`: there is an overall trend change occurring at this point + +Note that there must be at least 22 values for change point detection. Fewer than 1,000 is preferred. + +**Syntax** + +\`\`\` esql +CHANGE_POINT value [ON key] [AS type_name, pvalue_name] +\`\`\` + +**Parameters** + +* \`value\`: The column with the metric in which you want to detect a change point. +* \`key\`: The column with the key to order the values by. If not specified, @timestamp is used. +* \`type_name\`: The name of the output column with the change point type. If not specified, type is used. +* \`pvalue_name\`: The name of the output column with the p-value that indicates how extreme the change point is. If not specified, pvalue is used. + +**Example** + +The following example shows the detection of a step change: + +\`\`\` esql +ROW key=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25] +| MV_EXPAND key +| EVAL value = CASE(key<13, 0, 42) +| CHANGE_POINT value ON key +| WHERE type IS NOT NULL +\`\`\` + +| key:integer | value:integer | type:keyword | pvalue:double | +|-------------|---------------|--------------|---------------| +| 13 | 42 | step_change | 0.0 | + +`, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + openLinksInNewTab: true, + preview: true, + }, + { + name: 'completion', + labelDefaultMessage: 'COMPLETION', + descriptionDefaultMessage: `### COMPLETION + +The \`COMPLETION\` processing command uses a machine learning model to generate text completions based on the provided prompt. The command works with any LLM deployed to the [Elasticsearch inference API](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-inference-put) and can be chained with other ES|QL commands for further processing. + +**Syntax** + +\`\`\` esql +COMPLETION [column =] prompt WITH inference_id +\`\`\` + +**Parameters** + +* \`column\`: (Optional) The name of the output column that will contain the completion results. If not specified, the results will be stored in a column named \`completion\`. If the specified column already exists, it will be overwritten with the new completion results. +* \`prompt\`: The input text or expression that will be used as the prompt for the completion. This can be a string literal or a reference to a column containing text. +* \`inference_id\`: The ID of the inference endpoint to use for text completion. The inference endpoint must be configured with the \`completion\` task type. + +**Examples** + +The following is a basic example with an inline prompt: + +\`\`\` esql +ROW question = "What is Elasticsearch?" +| COMPLETION answer = question WITH test_completion_model +| KEEP question, answer +\`\`\` + +| question:keyword | answer:keyword | +|------------------|----------------| +| What is Elasticsearch? | A distributed search and analytics engine | + +This example uses a prompt constructed from multiple columns to generate a summary: + +\`\`\` esql +FROM movies +| SORT rating DESC +| LIMIT 10 +| EVAL prompt = CONCAT( + "Summarize this movie using the following information: \\\\n", + "Title: ", title, "\\\\n", + "Synopsis: ", synopsis, "\\\\n", + "Actors: ", MV_CONCAT(actors, ", "), "\\\\n", + ) +| COMPLETION summary = prompt WITH test_completion_model +| KEEP title, summary, rating +\`\`\` + +| title:keyword | summary:keyword | rating:double | +|---------------|-----------------|---------------| +| The Shawshank Redemption | A tale of hope and redemption in prison. | 9.3 | +| The Godfather | A mafia family's rise and fall. | 9.2 | +| The Dark Knight | Batman battles the Joker in Gotham. | 9.0 | +| Pulp Fiction | Interconnected crime stories with dark humor. | 8.9 | +| Fight Club | A man starts an underground fight club. | 8.8 | +| Inception | A thief steals secrets through dreams. | 8.8 | +| The Matrix | A hacker discovers reality is a simulation. | 8.7 | +| Parasite | Class conflict between two families. | 8.6 | +| Interstellar | A team explores space to save humanity. | 8.6 | +| The Prestige | Rival magicians engage in dangerous competition. | 8.5 | + +`, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like COMPLETION, prompt, inference_id', + }, + openLinksInNewTab: true, + preview: true, + }, + { + name: 'dissect', + labelDefaultMessage: 'DISSECT', + descriptionDefaultMessage: `### DISSECT +\`DISSECT\` enables you to extract structured data out of a string. \`DISSECT\` matches the string against a delimiter-based pattern, and extracts the specified keys as columns. + +Refer to the [dissect processor documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/dissect-processor.html) for the syntax of dissect patterns. + +\`\`\` esql +ROW a = "1953-01-23T12:15:00Z - some text - 127.0.0.1" +| DISSECT a "%'\\{Y\\}-%\\{M\\}-%\\{D\\}T%\\{h\\}:%\\{m\\}:%\\{s\\}Z - %\\{msg\\} - %\\{ip\\}'" +\`\`\` `, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + openLinksInNewTab: true, + }, + { + name: 'drop', + labelDefaultMessage: 'DROP', + descriptionDefaultMessage: `### DROP +Use \`DROP\` to remove columns from a table: + +\`\`\` esql +FROM employees +| DROP height +\`\`\` + +Rather than specify each column by name, you can use wildcards to drop all columns with a name that matches a pattern: + +\`\`\` esql +FROM employees +| DROP height* +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'enrich', + labelDefaultMessage: 'ENRICH', + descriptionDefaultMessage: `### ENRICH +You can use \`ENRICH\` to add data from your existing indices to incoming records. It's similar to [ingest enrich](https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html), but it works at query time. + +\`\`\` esql +ROW language_code = "1" +| ENRICH languages_policy +\`\`\` + +\`ENRICH\` requires an [enrich policy](https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html#enrich-policy) to be executed. The enrich policy defines a match field (a key field) and a set of enrich fields. + +\`ENRICH\` will look for records in the [enrich index](https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html#enrich-index) based on the match field value. The matching key in the input dataset can be defined using \`ON \`; if it's not specified, the match will be performed on a field with the same name as the match field defined in the enrich policy. + +\`\`\` esql +ROW a = "1" +| ENRICH languages_policy ON a +\`\`\` + +You can specify which attributes (between those defined as enrich fields in the policy) have to be added to the result, using \`WITH , ...\` syntax. + +\`\`\` esql +ROW a = "1" +| ENRICH languages_policy ON a WITH language_name +\`\`\` + +Attributes can also be renamed using \`WITH new_name=\` + +\`\`\` esql +ROW a = "1" +| ENRICH languages_policy ON a WITH name = language_name +\`\`\` + +By default (if no \`WITH\` is defined), \`ENRICH\` will add all the enrich fields defined in the enrich policy to the result. + +In case of name collisions, the newly created fields will override the existing fields. + `, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + openLinksInNewTab: true, + }, + { + name: 'eval', + labelDefaultMessage: 'EVAL', + descriptionDefaultMessage: `### EVAL +\`EVAL\` enables you to add new columns: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, height +| EVAL height_feet = height * 3.281, height_cm = height * 100 +\`\`\` + +If the specified column already exists, the existing column will be dropped, and the new column will be appended to the table: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, height +| EVAL height = height * 3.281 +\`\`\` + +#### Functions +\`EVAL\` supports various functions for calculating values. Refer to Functions for more information. + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'grok', + labelDefaultMessage: 'GROK', + descriptionDefaultMessage: `### GROK +\`GROK\` enables you to extract structured data out of a string. \`GROK\` matches the string against patterns, based on regular expressions, and extracts the specified patterns as columns. + +Refer to the [grok processor documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/grok-processor.html) for the syntax of grok patterns. + +\`\`\` esql +ROW a = "12 15.5 15.6 true" +| GROK a "%'\\{NUMBER:b:int\\} %\\{NUMBER:c:float\\} %\\{NUMBER:d:double\\} %\\{WORD:e:boolean\\}'" +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + openLinksInNewTab: true, + }, + { + name: 'keep', + labelDefaultMessage: 'KEEP', + descriptionDefaultMessage: `### KEEP +The \`KEEP\` command enables you to specify what columns are returned and the order in which they are returned. + +To limit the columns that are returned, use a comma-separated list of column names. The columns are returned in the specified order: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, height +\`\`\` + +Rather than specify each column by name, you can use wildcards to return all columns with a name that matches a pattern: + +\`\`\` esql +FROM employees +| KEEP h* +\`\`\` + +The asterisk wildcard (\`*\`) by itself translates to all columns that do not match the other arguments. This query will first return all columns with a name that starts with an h, followed by all other columns: + +\`\`\` esql +FROM employees +| KEEP h*, * +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'limit', + labelDefaultMessage: 'LIMIT', + descriptionDefaultMessage: `### LIMIT +The \`LIMIT\` processing command enables you to limit the number of rows: + +\`\`\` esql +FROM employees +| LIMIT 5 +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'lookup', + labelDefaultMessage: 'LOOKUP JOIN', + descriptionDefaultMessage: `### LOOKUP JOIN +You can use \`LOOKUP JOIN\` to add data from an existing index to incoming rows. While this is similar to \`ENRICH\`, it does not require an enrich policy to be executed beforehand. Additionally, if multiple matching documents are found in the lookup index, they will generate multiple output rows. + +\`\`\` esql +ROW language_code = 1 +| LOOKUP JOIN languages ON language_code +\`\`\` + +An index that is used in \`LOOKUP JOIN\` needs to be in lookup mode. This [index mode](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings) needs to be set when the index is created. + +\`\`\` esql +PUT languages +'{ + "settings": { + "index":{ + "mode":"lookup" + } + } +}' +\`\`\` + +The join key field must have a compatible type and match the name of the field in the lookup index to find matching documents. You can use \`RENAME\` or \`EVAL\` to rename columns as needed. + +\`\`\` esql +FROM employees +| EVAL language_code = languages +| LOOKUP JOIN languages ON language_code +\`\`\` + +In case of name collisions, the fields from the lookup index will override the existing fields. + `, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + openLinksInNewTab: true, + preview: false, + }, + { + name: 'mv_expand', + labelDefaultMessage: 'MV_EXPAND', + descriptionDefaultMessage: `### MV_EXPAND +The \`MV_EXPAND\` processing command expands multivalued fields into one row per value, duplicating other fields: +\`\`\` esql +ROW a=[1,2,3], b="b", j=["a","b"] +| MV_EXPAND a +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + preview: true, + }, + { + name: 'rename', + labelDefaultMessage: 'RENAME', + descriptionDefaultMessage: `### RENAME +Use \`RENAME\` to rename a column using the following syntax: + +\`\`\` esql +RENAME AS +\`\`\` + +For example: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, still_hired +| RENAME still_hired AS employed +\`\`\` + +If a column with the new name already exists, it will be replaced by the new column. + +Multiple columns can be renamed with a single \`RENAME\` command: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name +| RENAME first_name AS fn, last_name AS ln +\`\`\` + `, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'sample', + labelDefaultMessage: 'SAMPLE', + descriptionDefaultMessage: `### SAMPLE +The \`SAMPLE\` command samples a fraction of the table rows. + +**Syntax** + +\`\`\` esql +SAMPLE probability +\`\`\` + +**Parameters** + +* \`probability\`: The probability that a row is included in the sample. The value must be between 0 and 1, exclusive. + +**Example** + +The following example shows the detection of a step change: + +\`\`\` esql +FROM employees +| KEEP emp_no +| SAMPLE 0.05 +\`\`\` + +| emp_no:integer | +|----------------| +| 10018 | +| 10024 | +| 10062 | +| 10081 | + +`, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + openLinksInNewTab: true, + preview: true, + }, + { + name: 'sort', + labelDefaultMessage: 'SORT', + descriptionDefaultMessage: `### SORT +Use the \`SORT\` command to sort rows on one or more fields: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, height +| SORT height +\`\`\` + +The default sort order is ascending. Set an explicit sort order using \`ASC\` or \`DESC\`: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, height +| SORT height DESC +\`\`\` + +If two rows have the same sort key, the original order will be preserved. You can provide additional sort expressions to act as tie breakers: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, height +| SORT height DESC, first_name ASC +\`\`\` + +#### \`null\` values +By default, \`null\` values are treated as being larger than any other value. With an ascending sort order, \`null\` values are sorted last, and with a descending sort order, \`null\` values are sorted first. You can change that by providing \`NULLS FIRST\` or \`NULLS LAST\`: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, height +| SORT first_name ASC NULLS FIRST +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'stats', + labelDefaultMessage: 'STATS ... BY', + descriptionDefaultMessage: `### STATS ... BY +Use \`STATS ... BY\` to group rows according to a common value and calculate one or more aggregated values over the grouped rows. + +**Examples**: + +\`\`\` esql +FROM employees +| STATS count = COUNT(emp_no) BY languages +| SORT languages +\`\`\` + +If \`BY\` is omitted, the output table contains exactly one row with the aggregations applied over the entire dataset: + +\`\`\` esql +FROM employees +| STATS avg_lang = AVG(languages) +\`\`\` + +It's possible to calculate multiple values: + +\`\`\` esql +FROM employees +| STATS avg_lang = AVG(languages), max_lang = MAX(languages) +\`\`\` + +It's also possible to group by multiple values (only supported for long and keyword family fields): + +\`\`\` esql +FROM employees +| EVAL hired = DATE_FORMAT(hire_date, "YYYY") +| STATS avg_salary = AVG(salary) BY hired, languages.long +| EVAL avg_salary = ROUND(avg_salary) +| SORT hired, languages.long +\`\`\` + +Refer to **Aggregation functions** for a list of functions that can be used with \`STATS ... BY\`. + +Both the aggregating functions and the grouping expressions accept other functions. This is useful for using \`STATS...BY\` on multivalue columns. For example, to calculate the average salary change, you can use \`MV_AVG\` to first average the multiple values per employee, and use the result with the \`AVG\` function: + +\`\`\` esql +FROM employees +| STATS avg_salary_change = AVG(MV_AVG(salary_change)) +\`\`\` + +An example of grouping by an expression is grouping employees on the first letter of their last name: + +\`\`\` esql +FROM employees +| STATS my_count = COUNT() BY LEFT(last_name, 1) +| SORT \`LEFT(last_name, 1)\` +\`\`\` + +Specifying the output column name is optional. If not specified, the new column name is equal to the expression. The following query returns a column named \`AVG(salary)\`: + +\`\`\` esql +FROM employees +| STATS AVG(salary) +\`\`\` + +Because this name contains special characters, it needs to be quoted with backticks (\`) when using it in subsequent commands: + +\`\`\` esql +FROM employees +| STATS AVG(salary) +| EVAL avg_salary_rounded = ROUND(\`AVG(salary)\`) +\`\`\` + +**Note**: \`STATS\` without any groups is much faster than adding a group. + +**Note**: Grouping on a single expression is currently much more optimized than grouping on many expressions. + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'where', + labelDefaultMessage: 'WHERE', + descriptionDefaultMessage: `### WHERE +Use \`WHERE\` to produce a table that contains all the rows from the input table for which the provided condition evaluates to \`true\`: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, still_hired +| WHERE still_hired == true +\`\`\` + +#### Operators + +Refer to **Operators** for an overview of the supported operators. + +#### Functions +\`WHERE\` supports various functions for calculating values. Refer to **Functions** for more information. + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, +]; diff --git a/src/platform/packages/private/kbn-language-documentation/scripts/resources/commands/source_data.ts b/src/platform/packages/private/kbn-language-documentation/scripts/resources/commands/source_data.ts new file mode 100644 index 0000000000000..372e5a3c8e459 --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/scripts/resources/commands/source_data.ts @@ -0,0 +1,117 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +// Template data for ESQL command documentation +// The generate_esql_command_docs.ts script will convert this to TSX with React components + +export const sourceCommandsIntro = { + labelKey: 'languageDocumentation.documentationESQL.sourceCommands', + labelDefaultMessage: 'Source commands', + descriptionKey: 'languageDocumentation.documentationESQL.commandsDescription', + descriptionDefaultMessage: `A source command produces a table, typically with data from Elasticsearch. ES|QL supports the following source commands.`, +}; + +export const sourceCommandsItems = [ + { + name: 'from', + labelDefaultMessage: 'FROM', + descriptionDefaultMessage: `### FROM +The \`FROM\` source command returns a table with up to 10,000 documents from a data stream, index, or alias. Each row in the resulting table represents a document. Each column corresponds to a field, and can be accessed by the name of that field. + +\`\`\` esql +FROM employees +\`\`\` + +You can use [date math](https://www.elastic.co/guide/en/elasticsearch/reference/current/api-conventions.html#api-date-math-index-names) to refer to indices, aliases and data streams. This can be useful for time series data. + +Use comma-separated lists or wildcards to query multiple data streams, indices, or aliases: + +\`\`\` esql +FROM employees-00001,employees-* +\`\`\` + +#### Metadata + +ES|QL can access the following metadata fields: + +* \`_index\`: the index to which the document belongs. The field is of the type \`keyword\`. +* \`_id\`: the source document's ID. The field is of the type \`keyword\`. +* \`_version\`: the source document's version. The field is of the type \`long\`. + +Use the \`METADATA\` directive to enable metadata fields: + +\`\`\` esql +FROM index METADATA _index, _id +\`\`\` + +Metadata fields are only available if the source of the data is an index. Consequently, \`FROM\` is the only source commands that supports the \`METADATA\` directive. + +Once enabled, the fields are then available to subsequent processing commands, just like the other index fields: + +\`\`\` esql +FROM ul_logs, apps METADATA _index, _version +| WHERE id IN (13, 14) AND _version == 1 +| EVAL key = CONCAT(_index, "_", TO_STR(id)) +| SORT id, _index +| KEEP id, _index, _version, key +\`\`\` + +Also, similar to the index fields, once an aggregation is performed, a metadata field will no longer be accessible to subsequent commands, unless used as grouping field: + +\`\`\` esql +FROM employees METADATA _index, _id +| STATS max = MAX(emp_no) BY _index +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + openLinksInNewTab: true, + }, + { + name: 'row', + labelDefaultMessage: 'ROW', + descriptionDefaultMessage: `### ROW +The \`ROW\` source command produces a row with one or more columns with values that you specify. This can be useful for testing. + +\`\`\` esql +ROW a = 1, b = "two", c = null +\`\`\` + +Use square brackets to create multi-value columns: + +\`\`\` esql +ROW a = [2, 1] +\`\`\` + +ROW supports the use of functions: + +\`\`\` esql +ROW a = ROUND(1.23, 0) +\`\`\` + `, + descriptionOptions: { + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, + { + name: 'show', + labelDefaultMessage: 'SHOW', + descriptionDefaultMessage: `### SHOW +The \`SHOW INFO\` source command returns the deployment's version, build date and hash. + `, + descriptionOptions: { + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + }, + }, +]; diff --git a/src/platform/packages/private/kbn-language-documentation/scripts/scripts.constants.ts b/src/platform/packages/private/kbn-language-documentation/scripts/scripts.constants.ts new file mode 100644 index 0000000000000..6d6c42cc7f2d3 --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/scripts/scripts.constants.ts @@ -0,0 +1,26 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import path from 'path'; + +// Base path for ESQL documentation within the elasticsearch repository +export const ELASTISEARCH_ESQL_DOCS_BASE_PATH = path.join( + 'docs', + 'reference', + 'query-languages', + 'esql', + 'kibana' +); + +// Suffixes for specific elasticsearch ESQL content directories +export const DEFINITION_DIR_SUFFIX = 'definition'; +export const DOCS_DIR_SUFFIX = 'docs'; + +// Output directory for the generated files relative to the scripts +export const OUTPUT_DIR = path.resolve(__dirname, '../src/sections/generated'); diff --git a/src/platform/packages/private/kbn-language-documentation/src/components/shared/documentation_content.tsx b/src/platform/packages/private/kbn-language-documentation/src/components/shared/documentation_content.tsx index ea000a8770e09..9c78e293be88a 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/components/shared/documentation_content.tsx +++ b/src/platform/packages/private/kbn-language-documentation/src/components/shared/documentation_content.tsx @@ -11,8 +11,8 @@ import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; import { useEuiTheme, euiScrollBarStyles } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiText, EuiBetaBadge } from '@elastic/eui'; -import type { LanguageDocumentationSections } from '../../types'; -import { LicenseInfo, MultipleLicenseInfo, getLicensesArray } from '../../utils/get_license_array'; +import type { LanguageDocumentationSections, LicenseInfo, MultipleLicenseInfo } from '../../types'; +import { getLicensesArray } from '../../utils/get_license_array'; function toTitleCase(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); diff --git a/src/platform/packages/private/kbn-language-documentation/src/sections/esql_documentation_sections.tsx b/src/platform/packages/private/kbn-language-documentation/src/sections/esql_documentation_sections.tsx index 52074cd89bc78..ae8d583f8e66b 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/sections/esql_documentation_sections.tsx +++ b/src/platform/packages/private/kbn-language-documentation/src/sections/esql_documentation_sections.tsx @@ -9,14 +9,12 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { Markdown as SharedUXMarkdown } from '@kbn/shared-ux-markdown'; - -const Markdown = (props: Parameters[0]) => ( - -); +import { Markdown } from '@kbn/shared-ux-markdown'; export const initialSection = ( ); -export const sourceCommands = { - label: i18n.translate('languageDocumentation.documentationESQL.sourceCommands', { - defaultMessage: 'Source commands', - }), - description: i18n.translate('languageDocumentation.documentationESQL.commandsDescription', { - defaultMessage: `A source command produces a table, typically with data from Elasticsearch. ES|QL supports the following source commands.`, - }), - items: [ - { - label: i18n.translate('languageDocumentation.documentationESQL.from', { - defaultMessage: 'FROM', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.row', { - defaultMessage: 'ROW', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.show', { - defaultMessage: 'SHOW', - }), - description: ( - - ), - }, - ], -}; - -export const processingCommands = { - label: i18n.translate('languageDocumentation.documentationESQL.processingCommands', { - defaultMessage: 'Processing commands', - }), - description: i18n.translate( - 'languageDocumentation.documentationESQL.processingCommandsDescription', - { - defaultMessage: `Processing commands change an input table by adding, removing, or changing rows and columns. ES|QL supports the following processing commands.`, - } - ), - items: [ - { - label: i18n.translate('languageDocumentation.documentationESQL.changePoint', { - defaultMessage: 'CHANGE_POINT', - }), - preview: true, - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.completionCommand', { - defaultMessage: 'COMPLETION', - }), - preview: true, - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.dissect', { - defaultMessage: 'DISSECT', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.drop', { - defaultMessage: 'DROP', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.enrich', { - defaultMessage: 'ENRICH', - }), - description: ( - \`; if it’s not specified, the match will be performed on a field with the same name as the match field defined in the enrich policy. - -\`\`\` esql -ROW a = "1" -| ENRICH languages_policy ON a -\`\`\` - -You can specify which attributes (between those defined as enrich fields in the policy) have to be added to the result, using \`WITH , ...\` syntax. - -\`\`\` esql -ROW a = "1" -| ENRICH languages_policy ON a WITH language_name -\`\`\` - -Attributes can also be renamed using \`WITH new_name=\` - -\`\`\` esql -ROW a = "1" -| ENRICH languages_policy ON a WITH name = language_name -\`\`\` - -By default (if no \`WITH\` is defined), \`ENRICH\` will add all the enrich fields defined in the enrich policy to the result. - -In case of name collisions, the newly created fields will override the existing fields. - `, - ignoreTag: true, - description: - 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', - } - )} - /> - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.eval', { - defaultMessage: 'EVAL', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.grok', { - defaultMessage: 'GROK', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.keep', { - defaultMessage: 'KEEP', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.limit', { - defaultMessage: 'LIMIT', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.lookupJoin', { - defaultMessage: 'LOOKUP JOIN', - }), - preview: false, - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.mvExpand', { - defaultMessage: 'MV_EXPAND', - }), - preview: true, - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.rename', { - defaultMessage: 'RENAME', - }), - description: ( - AS -\`\`\` - -For example: - -\`\`\` esql -FROM employees -| KEEP first_name, last_name, still_hired -| RENAME still_hired AS employed -\`\`\` - -If a column with the new name already exists, it will be replaced by the new column. - -Multiple columns can be renamed with a single \`RENAME\` command: - -\`\`\` esql -FROM employees -| KEEP first_name, last_name -| RENAME first_name AS fn, last_name AS ln -\`\`\` - `, - ignoreTag: true, - description: - 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', - } - )} - /> - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.sampleCommand', { - defaultMessage: 'SAMPLE', - }), - preview: true, - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.sort', { - defaultMessage: 'SORT', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.statsby', { - defaultMessage: 'STATS ... BY', - }), - description: ( - - ), - }, - { - label: i18n.translate('languageDocumentation.documentationESQL.where', { - defaultMessage: 'WHERE', - }), - description: ( - - ), - }, - ], -}; - +export { commands as sourceCommands } from './generated/source_commands'; +export { commands as processingCommands } from './generated/processing_commands'; export { functions as scalarFunctions } from './generated/scalar_functions'; export { functions as aggregationFunctions } from './generated/aggregation_functions'; export { functions as timeseriesAggregationFunctions } from './generated/timeseries_aggregation_functions'; diff --git a/src/platform/packages/private/kbn-language-documentation/src/sections/generated/processing_commands.tsx b/src/platform/packages/private/kbn-language-documentation/src/sections/generated/processing_commands.tsx new file mode 100644 index 0000000000000..fce0eb4bbbd48 --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/src/sections/generated/processing_commands.tsx @@ -0,0 +1,734 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { Markdown as SharedUXMarkdown } from '@kbn/shared-ux-markdown'; + +const Markdown = (props: Parameters[0]) => ( + +); + +// Do not edit manually... automatically generated by scripts/generate_esql_command_docs.ts + +export const commands = { + label: i18n.translate('languageDocumentation.documentationESQL.processingCommands', { + defaultMessage: 'Processing commands', + }), + description: i18n.translate( + 'languageDocumentation.documentationESQL.processingCommandsDescription', + { + defaultMessage: `Processing commands change an input table by adding, removing, or changing rows and columns. ES|QL supports the following processing commands.`, + } + ), + items: [ + { + label: i18n.translate('languageDocumentation.documentationESQL.change_point', { + defaultMessage: 'CHANGE_POINT', + }), + preview: true, + description: ( + + ), + license: { licenses: [{ name: 'PLATINUM' }], hasMultipleLicenses: false }, + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.completion', { + defaultMessage: 'COMPLETION', + }), + preview: true, + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.dissect', { + defaultMessage: 'DISSECT', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.drop', { + defaultMessage: 'DROP', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.enrich', { + defaultMessage: 'ENRICH', + }), + description: ( + \`; if it's not specified, the match will be performed on a field with the same name as the match field defined in the enrich policy. + +\`\`\` esql +ROW a = "1" +| ENRICH languages_policy ON a +\`\`\` + +You can specify which attributes (between those defined as enrich fields in the policy) have to be added to the result, using \`WITH , ...\` syntax. + +\`\`\` esql +ROW a = "1" +| ENRICH languages_policy ON a WITH language_name +\`\`\` + +Attributes can also be renamed using \`WITH new_name=\` + +\`\`\` esql +ROW a = "1" +| ENRICH languages_policy ON a WITH name = language_name +\`\`\` + +By default (if no \`WITH\` is defined), \`ENRICH\` will add all the enrich fields defined in the enrich policy to the result. + +In case of name collisions, the newly created fields will override the existing fields. + `, + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + } + )} + /> + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.eval', { + defaultMessage: 'EVAL', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.grok', { + defaultMessage: 'GROK', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.keep', { + defaultMessage: 'KEEP', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.limit', { + defaultMessage: 'LIMIT', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.lookup', { + defaultMessage: 'LOOKUP JOIN', + }), + preview: false, + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.mv_expand', { + defaultMessage: 'MV_EXPAND', + }), + preview: true, + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.rename', { + defaultMessage: 'RENAME', + }), + description: ( + AS +\`\`\` + +For example: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name, still_hired +| RENAME still_hired AS employed +\`\`\` + +If a column with the new name already exists, it will be replaced by the new column. + +Multiple columns can be renamed with a single \`RENAME\` command: + +\`\`\` esql +FROM employees +| KEEP first_name, last_name +| RENAME first_name AS fn, last_name AS ln +\`\`\` + `, + ignoreTag: true, + description: + 'Text is in markdown. Do not translate function names, special characters, or field names like sum(bytes)', + } + )} + /> + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.sampleCommand', { + defaultMessage: 'SAMPLE', + }), + preview: true, + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.sort', { + defaultMessage: 'SORT', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.stats', { + defaultMessage: 'STATS ... BY', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.where', { + defaultMessage: 'WHERE', + }), + description: ( + + ), + }, + ], +}; diff --git a/src/platform/packages/private/kbn-language-documentation/src/sections/generated/scalar_functions.tsx b/src/platform/packages/private/kbn-language-documentation/src/sections/generated/scalar_functions.tsx index 932f16a7d2ee5..c18a2b8aa7eb9 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/sections/generated/scalar_functions.tsx +++ b/src/platform/packages/private/kbn-language-documentation/src/sections/generated/scalar_functions.tsx @@ -1297,7 +1297,7 @@ export const functions = { markdownContent={i18n.translate('languageDocumentation.documentationESQL.md5.markdown', { defaultMessage: ` ### MD5 - Computes the MD5 hash of the input (if the MD5 hash is available on the JVM). + Computes the MD5 hash of the input. \`\`\`esql FROM sample_data diff --git a/src/platform/packages/private/kbn-language-documentation/src/sections/generated/source_commands.tsx b/src/platform/packages/private/kbn-language-documentation/src/sections/generated/source_commands.tsx new file mode 100644 index 0000000000000..3d0c6e86d1db3 --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/src/sections/generated/source_commands.tsx @@ -0,0 +1,140 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { Markdown as SharedUXMarkdown } from '@kbn/shared-ux-markdown'; + +const Markdown = (props: Parameters[0]) => ( + +); + +// Do not edit manually... automatically generated by scripts/generate_esql_command_docs.ts + +export const commands = { + label: i18n.translate('languageDocumentation.documentationESQL.sourceCommands', { + defaultMessage: 'Source commands', + }), + description: i18n.translate('languageDocumentation.documentationESQL.commandsDescription', { + defaultMessage: `A source command produces a table, typically with data from Elasticsearch. ES|QL supports the following source commands.`, + }), + items: [ + { + label: i18n.translate('languageDocumentation.documentationESQL.from', { + defaultMessage: 'FROM', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.row', { + defaultMessage: 'ROW', + }), + description: ( + + ), + }, + { + label: i18n.translate('languageDocumentation.documentationESQL.show', { + defaultMessage: 'SHOW', + }), + description: ( + + ), + }, + ], +}; diff --git a/src/platform/packages/private/kbn-language-documentation/src/types.ts b/src/platform/packages/private/kbn-language-documentation/src/types.ts index 08326fe9321cc..914b49ae71f15 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/types.ts +++ b/src/platform/packages/private/kbn-language-documentation/src/types.ts @@ -17,6 +17,7 @@ export interface LanguageDocumentationSections { } export type ESQLSignatureLicenseType = 'PLATINUM' | 'BASIC' | 'GOLD' | 'ENTERPRISE'; + export interface Signature { params: Array<{ name: string; @@ -27,7 +28,30 @@ export interface Signature { license?: ESQLSignatureLicenseType; } +export interface CommandDefinition { + name: string; + observability_tier?: string; + license?: ESQLSignatureLicenseType; +} + export interface FunctionDefinition { + name: string; + snapshot_only: boolean; + type: string; + titleName: string; + operator: string; + preview: boolean; signatures: Signature[]; license?: ESQLSignatureLicenseType; } + +export interface LicenseInfo { + name: string; + isSignatureSpecific?: boolean; + paramsWithLicense?: string[]; +} + +export interface MultipleLicenseInfo { + licenses: LicenseInfo[]; + hasMultipleLicenses: boolean; +} diff --git a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.test.ts b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.test.ts index 00d8e931de267..d39fa0d8fc84f 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.test.ts +++ b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.test.ts @@ -7,7 +7,8 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { MultipleLicenseInfo, getLicensesArray } from './get_license_array'; +import { MultipleLicenseInfo } from '../types'; +import { getLicensesArray } from './get_license_array'; describe('getLicensesArray', () => { test('should returns licenses array when valid MultipleLicenseInfo is provided', () => { diff --git a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.ts b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.ts index 0acbe7b7b3d19..59b2a7a951960 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.ts +++ b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_array.ts @@ -7,18 +7,9 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -// Helper function to get licenses array from either format - -export interface LicenseInfo { - name: string; - isSignatureSpecific?: boolean; - paramsWithLicense?: string[]; -} +import { LicenseInfo, MultipleLicenseInfo } from '../types'; -export interface MultipleLicenseInfo { - licenses: LicenseInfo[]; - hasMultipleLicenses: boolean; -} +// Helper function to get licenses array from either format export function getLicensesArray(license: MultipleLicenseInfo | undefined): LicenseInfo[] { if (license && Array.isArray(license.licenses)) { diff --git a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.test.ts b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.test.ts index 1886c17103b33..d232915f6b569 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.test.ts +++ b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.test.ts @@ -8,16 +8,22 @@ */ import { FunctionDefinition } from '../types'; -import { getLicenseInfo } from './get_license_info'; +import { getLicenseInfoForFunctions } from './get_license_info'; describe('getLicenseInfo', () => { test('should returns top-level license if present', () => { const fn: FunctionDefinition = { - license: 'PLATINUM', + name: 'test_function', + snapshot_only: false, + type: 'function', + titleName: 'Test Function', + operator: '-', + preview: false, signatures: [], + license: 'PLATINUM', }; - const result = getLicenseInfo(fn); + const result = getLicenseInfoForFunctions(fn); expect(result).toEqual({ licenses: [ @@ -33,14 +39,16 @@ describe('getLicenseInfo', () => { test('should returns undefined if no license exists', () => { const fn: FunctionDefinition = { - signatures: [ - { - params: [{ name: 'x', type: 'string' }], - }, - ], + name: 'test_function_no_license', + snapshot_only: false, + type: 'string', + titleName: 'Test Function No License', + operator: '-', + preview: false, + signatures: [], }; - const result = getLicenseInfo(fn); + const result = getLicenseInfoForFunctions(fn); expect(result).toBeUndefined(); }); diff --git a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.ts b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.ts index 550744673ac7b..5adf4f3a19281 100644 --- a/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.ts +++ b/src/platform/packages/private/kbn-language-documentation/src/utils/get_license_info.ts @@ -7,20 +7,9 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { FunctionDefinition } from '../types'; +import { CommandDefinition, FunctionDefinition, LicenseInfo, MultipleLicenseInfo } from '../types'; import { aggregateLicensesFromSignatures } from './aggregate_licenses_from_signatures'; -interface LicenseInfo { - name: string; - isSignatureSpecific: boolean; - paramsWithLicense: string[]; -} - -interface MultipleLicenseInfo { - licenses: LicenseInfo[]; - hasMultipleLicenses: boolean; -} - /** * Transforms the aggregated license map into the final array of LicenseInfo objects. */ @@ -35,7 +24,7 @@ function transformLicenseMap(licensesMap: Map>): LicenseInfo }); } -export function getLicenseInfo( +export function getLicenseInfoForFunctions( fnDefinition: FunctionDefinition | undefined ): MultipleLicenseInfo | undefined { if (!fnDefinition) { @@ -69,3 +58,23 @@ export function getLicenseInfo( hasMultipleLicenses: licenses.length > 1, }; } + +/** + * Creates license info structure for commands. + */ +export function getLicenseInfoForCommand( + commandDef: CommandDefinition | undefined +): MultipleLicenseInfo | undefined { + if (!commandDef || !commandDef.license) { + return undefined; + } + + return { + licenses: [ + { + name: commandDef.license, + }, + ], + hasMultipleLicenses: false, + }; +} diff --git a/src/platform/packages/private/kbn-language-documentation/src/utils/load_elastic_definitions.test.ts b/src/platform/packages/private/kbn-language-documentation/src/utils/load_elastic_definitions.test.ts new file mode 100644 index 0000000000000..2363b639053b8 --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/src/utils/load_elastic_definitions.test.ts @@ -0,0 +1,74 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import * as fs from 'fs'; +import { loadElasticDefinitions } from './load_elastic_definitions'; + +jest.mock('fs'); +const mockedFs = fs as jest.Mocked; + +describe('loadElasticDefinitions', () => { + const mockDefinitionsPath = '/mock/path'; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + test('should load and return definitions from JSON files', () => { + const mockFiles = ['sample1.json', 'sample2.json', 'sample3.txt']; + const mockDefinition1 = { name: 'sample1', type: 'source' }; + const mockDefinition2 = { name: 'sample2', type: 'processing' }; + + mockedFs.readdirSync.mockReturnValue(mockFiles as any); + mockedFs.readFileSync + .mockReturnValueOnce(JSON.stringify(mockDefinition1)) + .mockReturnValueOnce(JSON.stringify(mockDefinition2)); + + const result = loadElasticDefinitions(mockDefinitionsPath); + + expect(result.size).toBe(2); + expect(result.get('sample1')).toEqual(mockDefinition1); + expect(result.get('sample2')).toEqual(mockDefinition2); + }); + + test('should filter out non-JSON files', () => { + const mockFiles = ['sample1.json', 'readme.md', 'sample2.json', 'config.txt']; + const mockDefinition1 = { name: 'sample1', type: 'source' }; + const mockDefinition2 = { name: 'sample2', type: 'processing' }; + + mockedFs.readdirSync.mockReturnValue(mockFiles as any); + mockedFs.readFileSync + .mockReturnValueOnce(JSON.stringify(mockDefinition1)) + .mockReturnValueOnce(JSON.stringify(mockDefinition2)); + + const result = loadElasticDefinitions(mockDefinitionsPath); + + expect(result.size).toBe(2); + }); + + test('should handle empty directory', () => { + mockedFs.readdirSync.mockReturnValue([] as any); + + const result = loadElasticDefinitions(mockDefinitionsPath); + + expect(result.size).toBe(0); + }); + + test('should use definition name as map key', () => { + const mockFiles = ['file1.json']; + const mockDefinition = { name: 'customName', otherProp: 'value' }; + + mockedFs.readdirSync.mockReturnValue(mockFiles as any); + mockedFs.readFileSync.mockReturnValue(JSON.stringify(mockDefinition)); + + const result = loadElasticDefinitions(mockDefinitionsPath); + + expect(result.get('customName')).toEqual(mockDefinition); + }); +}); diff --git a/src/platform/packages/private/kbn-language-documentation/src/utils/load_elastic_definitions.ts b/src/platform/packages/private/kbn-language-documentation/src/utils/load_elastic_definitions.ts new file mode 100644 index 0000000000000..c19108eb492e3 --- /dev/null +++ b/src/platform/packages/private/kbn-language-documentation/src/utils/load_elastic_definitions.ts @@ -0,0 +1,27 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import * as fs from 'fs'; +import * as path from 'path'; + +/** + * Loads definitions from JSON files in the specified directory. + * Returns a Map where the key is the definition name and the value is the parsed definition. + */ +export function loadElasticDefinitions(definitionsPath: string): Map { + const definitionEntries = fs + .readdirSync(definitionsPath) + .filter((file) => path.extname(file) === '.json') + .map((file): [string, T] => { + const definition = JSON.parse(fs.readFileSync(path.join(definitionsPath, file), 'utf-8')); + return [definition.name, definition]; + }); + + return new Map(definitionEntries); +} diff --git a/x-pack/platform/plugins/private/translations/translations/de-DE.json b/x-pack/platform/plugins/private/translations/translations/de-DE.json index 2134304e11ee4..f40fdd855c6f0 100644 --- a/x-pack/platform/plugins/private/translations/translations/de-DE.json +++ b/x-pack/platform/plugins/private/translations/translations/de-DE.json @@ -5508,8 +5508,8 @@ "languageDocumentation.documentationESQL.log.markdown": " ### LOG Gibt den Logarithmus eines Wertes zu einer Basis zurück. Der Eingang kann ein beliebiger numerischer Wert sein, der Rückgabewert ist immer ein Double. Logs von null, negativen Zahlen und der Basis eins geben `null` sowie eine Warnung zurück. ``` ROW Basis = 2,0, Wert = 8,0 | EVAL s = LOG(Basis, Wert) ```", "languageDocumentation.documentationESQL.log10": "LOG10", "languageDocumentation.documentationESQL.log10.markdown": " ### LOG10 Gibt den Logarithmus eines Wertes zur Basis 10 zurück. Die Eingabe kann ein beliebiger numerischer Wert sein, der Rückgabewert ist immer ein Double. Logarithmen von 0 und negativen Zahlen geben „null“ sowie eine Warnung zurück. ``` ROW d = 1000.0 | EVAL s = LOG10(d) ```", - "languageDocumentation.documentationESQL.lookupJoin": "LOOKUP JOIN", - "languageDocumentation.documentationESQL.lookupJoin.markdown": "### LOOKUP JOIN Sie können `LOOKUP JOIN` verwenden, um Daten aus einem vorhandenen Index zu eingehenden Zeilen hinzuzufügen. Obwohl dies `ENRICH` ähnelt, erfordert es nicht, dass zuvor eine Anreicherungsrichtlinie ausgeführt wird. Zusätzlich, wenn mehrere übereinstimmende Dokumente im Lookup-Index gefunden werden, erzeugen sie mehrere Ausgang Reihen. ``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` Ein Index, der in `LOOKUP JOIN` verwendet wird, muss sich im Lookup-Modus befinden. Dieser [Indexmodus](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings) muss beim Erstellen des Indexes festgelegt werden. ```PUT languages '{\"settings\": {\"index\":{ \"mode\":\"lookup\" } } }'``` Das Join-Schlüsselfeld muss einen kompatiblen Typ haben und mit dem Namen des Felds im Lookup-Index übereinstimmen, um passende Dokumente zu finden. Sie können `RENAME` oder `EVAL` verwenden, um Spalten nach Bedarf umzubenennen. ``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` Im Falle von Namenskollisionen überschreiben die Felder aus dem Lookup-Index die vorhandenen Felder.", + "languageDocumentation.documentationESQL.lookup": "LOOKUP JOIN", + "languageDocumentation.documentationESQL.lookup.markdown": "### LOOKUP JOIN Sie können `LOOKUP JOIN` verwenden, um Daten aus einem vorhandenen Index zu eingehenden Zeilen hinzuzufügen. Obwohl dies `ENRICH` ähnelt, erfordert es nicht, dass zuvor eine Anreicherungsrichtlinie ausgeführt wird. Zusätzlich, wenn mehrere übereinstimmende Dokumente im Lookup-Index gefunden werden, erzeugen sie mehrere Ausgang Reihen. ``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` Ein Index, der in `LOOKUP JOIN` verwendet wird, muss sich im Lookup-Modus befinden. Dieser [Indexmodus](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings) muss beim Erstellen des Indexes festgelegt werden. ```PUT languages '{\"settings\": {\"index\":{ \"mode\":\"lookup\" } } }'``` Das Join-Schlüsselfeld muss einen kompatiblen Typ haben und mit dem Namen des Felds im Lookup-Index übereinstimmen, um passende Dokumente zu finden. Sie können `RENAME` oder `EVAL` verwenden, um Spalten nach Bedarf umzubenennen. ``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` Im Falle von Namenskollisionen überschreiben die Felder aus dem Lookup-Index die vorhandenen Felder.", "languageDocumentation.documentationESQL.ltrim": "LTRIM", "languageDocumentation.documentationESQL.ltrim.markdown": " ### LTRIM Entfernt führende Leerzeichen aus einer Zeichenfolge. ``` ROW message = \" some text \", color = \" red \" | EVAL message = LTRIM(message) | EVAL color = LTRIM(color) | EVAL message = CONCAT(\"'\", message, \"'\") | EVAL color = CONCAT(\"'\", color, \"'\") ```", "languageDocumentation.documentationESQL.markdown": "Eine ES|QL (Elasticsearch Abfragesprache)-Abfrage besteht aus einer Reihe von Befehlen, die durch Pipe-Zeichen (`|`) getrennt sind. Jede Abfrage beginnt mit einem **Quellbefehl**, der eine Tabelle erstellt, typischerweise mit Daten von Elasticsearch. Ein Quellbefehl kann von einem oder mehreren **Verarbeitungsbefehlen** gefolgt werden. Verarbeitungsbefehle können die Ausgangstabelle des vorherigen Befehls durch Hinzufügen, Entfernen und Ändern von Zeilen und Spalten ändern. ``` source-command | processing-command1 | processing-command2 ``` Das Ergebnis einer Abfrage ist die Tabelle, die durch den letzten Verarbeitungsbefehl erzeugt wird.", @@ -5559,8 +5559,8 @@ "languageDocumentation.documentationESQL.mv_sum.markdown": " ### MV_SUM Konvertiert ein mehrwertiges Feld in ein einwertiges Feld, das die Summe aller Werte enthält. ``` ROW a=[3, 5, 6] | EVAL sum_a = MV_SUM(a) ```", "languageDocumentation.documentationESQL.mv_zip": "MV_ZIP", "languageDocumentation.documentationESQL.mv_zip.markdown": " ### MV_ZIP Kombiniert die Werte aus zwei mehrwertigen Feldern mit einem Trennzeichen, das sie verbindet. ``` ROW a = [\"x\", \"y\", \"z\"], b = [\"1\", \"2\"] | EVAL c = mv_zip(a, b, \"-\") | KEEP a, b, c ```", - "languageDocumentation.documentationESQL.mvExpand": "MV_EXPAND", - "languageDocumentation.documentationESQL.mvExpand.markdown": "### MV_EXPAND Der Verarbeitungsbefehl `MV_EXPAND` expandiert mehrwertige Felder in eine Zeile pro Wert und dupliziert andere Felder: ``` ROW a=[1,2,3], b=\"b\", j=[\"a\",\"b\"] | MV_EXPAND a ```", + "languageDocumentation.documentationESQL.mv_expand": "MV_EXPAND", + "languageDocumentation.documentationESQL.mv_expand.markdown": "### MV_EXPAND Der Verarbeitungsbefehl `MV_EXPAND` expandiert mehrwertige Felder in eine Zeile pro Wert und dupliziert andere Felder: ``` ROW a=[1,2,3], b=\"b\", j=[\"a\",\"b\"] | MV_EXPAND a ```", "languageDocumentation.documentationESQL.now": "JETZT", "languageDocumentation.documentationESQL.now.markdown": " ### NOW Gibt das aktuelle Datum und die aktuelle Uhrzeit zurück. ``` ROW current_date = NOW() ```", "languageDocumentation.documentationESQL.operators": "Operatoren", @@ -5641,8 +5641,8 @@ "languageDocumentation.documentationESQL.st_ymin.markdown": " ### ST_YMIN Extrahiert den Minimalwert der `y`-Koordinaten aus der bereitgestellten Geometrie. Wenn die Geometrie vom Typ `geo_point` oder `geo_shape` ist, entspricht dies der Extraktion des minimalen `latitude`-Wertes. ``` FROM airport_city_boundaries | WHERE abbrev == \"CPH\" | EVAL envelope = ST_ENVELOPE(city_boundary) | EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope) | KEEP abbrev, airport, xmin, xmax, ymin, ymax ```", "languageDocumentation.documentationESQL.starts_with": "BEGINNT_MIT", "languageDocumentation.documentationESQL.starts_with.markdown": " ### STARTS_WITH Gibt einen booleschen Wert zurück, der angibt, ob eine Schlüsselwortzeichenfolge mit einer anderen Zeichenfolge beginnt. ``` FROM employees | KEEP nachname | EVAL ln_S = STARTS_WITH(nachname, \"B\") ```", - "languageDocumentation.documentationESQL.statsby": "STATISTIKEN ... BY", - "languageDocumentation.documentationESQL.statsby.markdown": "### STATS ... BY Verwenden Sie „STATS ... BY“, um Zeilen nach einem gemeinsamen Wert zu gruppieren und einen oder mehrere aggregierte Werte über die gruppierten Zeilen zu berechnen. **Beispiele**: ``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` Wenn `BY` weggelassen wird, enthält die Ausgangstabelle genau eine Zeile, wobei die Aggregationen auf den gesamten Datensatz angewendet werden: ``` FROM employees | STATS avg_lang = AVG(languages) ``` Es ist möglich, mehrere Werte zu berechnen: ``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` Es ist auch möglich, nach mehreren Werten zu gruppieren (nur für long- und Keyword-Felder unterstützt): ``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long ``` Eine Liste der Funktionen, die mit `STATS ... BY` verwendet werden können, finden Sie unter **Aggregationsfunktionen**. Sowohl die Aggregationsfunktionen als auch die Gruppierungsausdrücke akzeptieren andere Funktionen. Dies ist nützlich für die Verwendung von „STATS...BY“ bei Spalten mit Mehrfachwerten. Um beispielsweise die durchschnittliche Gehaltsänderung zu berechnen, können Sie `MV_AVG` verwenden, um zuerst die verschiedenen Werte pro Mitarbeiter zu mitteln, und das Ergebnis mit der Funktion `AVG` verwenden: ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` Ein Beispiel für die Gruppierung nach einem Ausdruck ist die Gruppierung von Mitarbeitern nach dem ersten Buchstaben ihres Nachnamens: ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` Die Angabe des Namens der Ausgabespalte ist optional. Wenn nicht angegeben, ist der neue Spaltenname gleich dem Ausdruck. Die folgende Abfrage gibt eine Spalte mit dem Namen `AVG(salary)` zurück: ``` FROM employees | STATS AVG(salary) ``` Da dieser Name Sonderzeichen enthält, muss er mit Backticks (`) in Anführungszeichen gesetzt werden, wenn Sie ihn in nachfolgenden Befehlen verwenden: ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **Hinweis**: `STATS` ohne Gruppen ist viel schneller als das Hinzufügen einer Gruppe. **Hinweis**: Die Gruppierung auf einen einzelnen Ausdruck ist derzeit wesentlich optimierter als die Gruppierung auf mehrere Ausdrücke.", + "languageDocumentation.documentationESQL.stats": "STATISTIKEN ... BY", + "languageDocumentation.documentationESQL.stats.markdown": "### STATS ... BY Verwenden Sie „STATS ... BY“, um Zeilen nach einem gemeinsamen Wert zu gruppieren und einen oder mehrere aggregierte Werte über die gruppierten Zeilen zu berechnen. **Beispiele**: ``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` Wenn `BY` weggelassen wird, enthält die Ausgangstabelle genau eine Zeile, wobei die Aggregationen auf den gesamten Datensatz angewendet werden: ``` FROM employees | STATS avg_lang = AVG(languages) ``` Es ist möglich, mehrere Werte zu berechnen: ``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` Es ist auch möglich, nach mehreren Werten zu gruppieren (nur für long- und Keyword-Felder unterstützt): ``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long ``` Eine Liste der Funktionen, die mit `STATS ... BY` verwendet werden können, finden Sie unter **Aggregationsfunktionen**. Sowohl die Aggregationsfunktionen als auch die Gruppierungsausdrücke akzeptieren andere Funktionen. Dies ist nützlich für die Verwendung von „STATS...BY“ bei Spalten mit Mehrfachwerten. Um beispielsweise die durchschnittliche Gehaltsänderung zu berechnen, können Sie `MV_AVG` verwenden, um zuerst die verschiedenen Werte pro Mitarbeiter zu mitteln, und das Ergebnis mit der Funktion `AVG` verwenden: ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` Ein Beispiel für die Gruppierung nach einem Ausdruck ist die Gruppierung von Mitarbeitern nach dem ersten Buchstaben ihres Nachnamens: ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` Die Angabe des Namens der Ausgabespalte ist optional. Wenn nicht angegeben, ist der neue Spaltenname gleich dem Ausdruck. Die folgende Abfrage gibt eine Spalte mit dem Namen `AVG(salary)` zurück: ``` FROM employees | STATS AVG(salary) ``` Da dieser Name Sonderzeichen enthält, muss er mit Backticks (`) in Anführungszeichen gesetzt werden, wenn Sie ihn in nachfolgenden Befehlen verwenden: ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **Hinweis**: `STATS` ohne Gruppen ist viel schneller als das Hinzufügen einer Gruppe. **Hinweis**: Die Gruppierung auf einen einzelnen Ausdruck ist derzeit wesentlich optimierter als die Gruppierung auf mehrere Ausdrücke.", "languageDocumentation.documentationESQL.std_dev": "STD_DEV", "languageDocumentation.documentationESQL.std_dev.markdown": " ### STD_DEV Die Standardabweichung eines numerischen Feldes. ``` FROM employees | STATS STD_DEV(height) ```", "languageDocumentation.documentationESQL.substring": "SUBSTRING", diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 64d3ab95c4753..8ef1a1ebb4a1e 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -5528,8 +5528,8 @@ "languageDocumentation.documentationESQL.log.markdown": " ### LOG Renvoie le logarithme d'une valeur dans une base. La valeur de renvoi est toujours un double, quelle que soit la valeur numérique de l'entrée. Les journaux de zéros, de nombres négatifs et de base 1 renvoient \"null\" ainsi qu'un avertissement. ``` ROW base = 2.0, value = 8.0 | EVAL s = LOG(base, value) ```", "languageDocumentation.documentationESQL.log10": "LOG10", "languageDocumentation.documentationESQL.log10.markdown": " ### LOG10 Renvoie le logarithme d'une valeur en base 10. La valeur de renvoi est toujours un double, quelle que soit la valeur numérique de l'entrée. Les logs de 0 et de nombres négatifs renvoient \"null\" ainsi qu'un avertissement. ``` ROW d = 1000.0 | EVAL s = LOG10(d) ```", - "languageDocumentation.documentationESQL.lookupJoin": "LOOKUP JOIN", - "languageDocumentation.documentationESQL.lookupJoin.markdown": "### LOOKUP JOIN Vous pouvez utiliser \"LOOKUP JOIN\" pour ajouter des données d'un index existant aux lignes suivantes. Bien que cette commande soit similaire à \"ENRICH\", elle ne nécessite pas de politique d'enrichissement préalable pour être exécutée. De plus, si plusieurs documents correspondants sont trouvés dans l'index de consultation, ils généreront plusieurs lignes de sortie. ``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` Un index utilisé dans \"LOOKUP JOIN\" doit être en mode consultation. Ce [mode d'indexation](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings) doit être défini lors de la création de l'index. ``` PUT languages '{ \"settings\": { \"index\":{ \"mode\":\"lookup\" } } }' ``` Le champ \"join key\" doit avoir un type compatible et correspondre au nom du champ dans l'index de consultation afin de trouver des documents correspondants. Vous pouvez utiliser \"RENAME\" ou \"EVAL\" pour renommer les colonnes si nécessaire. ``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` En cas de collision de noms, les champs de l'index de consultation remplaceront les champs existants.", + "languageDocumentation.documentationESQL.lookup": "LOOKUP JOIN", + "languageDocumentation.documentationESQL.lookup.markdown": "### LOOKUP JOIN Vous pouvez utiliser \"LOOKUP JOIN\" pour ajouter des données d'un index existant aux lignes suivantes. Bien que cette commande soit similaire à \"ENRICH\", elle ne nécessite pas de politique d'enrichissement préalable pour être exécutée. De plus, si plusieurs documents correspondants sont trouvés dans l'index de consultation, ils généreront plusieurs lignes de sortie. ``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` Un index utilisé dans \"LOOKUP JOIN\" doit être en mode consultation. Ce [mode d'indexation](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings) doit être défini lors de la création de l'index. ``` PUT languages '{ \"settings\": { \"index\":{ \"mode\":\"lookup\" } } }' ``` Le champ \"join key\" doit avoir un type compatible et correspondre au nom du champ dans l'index de consultation afin de trouver des documents correspondants. Vous pouvez utiliser \"RENAME\" ou \"EVAL\" pour renommer les colonnes si nécessaire. ``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` En cas de collision de noms, les champs de l'index de consultation remplaceront les champs existants.", "languageDocumentation.documentationESQL.ltrim": "LTRIM", "languageDocumentation.documentationESQL.ltrim.markdown": " ### LTRIM Supprime les espaces au début d'une chaîne. ``` ROW message = \" some text \", color = \" red \" | EVAL message = LTRIM(message) | EVAL color = LTRIM(color) | EVAL message = CONCAT(\"'\", message, \"'\") | EVAL color = CONCAT(\"'\", color, \"'\") ```", "languageDocumentation.documentationESQL.markdown": "Une requête ES|QL (langage de requête Elasticsearch) se compose d'une série de commandes, séparées par une barre verticale : `|`. Chaque requête commence par une **commande source**, qui produit un tableau, habituellement avec des données issues d'Elasticsearch. Une commande source peut être suivie d'une ou plusieurs **commandes de traitement**. Les commandes de traitement peuvent modifier le tableau de sortie de la commande précédente en ajoutant, supprimant ou modifiant les lignes et les colonnes. ``` source-command | processing-command1 | processing-command2 ``` Le résultat d'une requête est le tableau produit par la dernière commande de traitement.", @@ -5579,8 +5579,8 @@ "languageDocumentation.documentationESQL.mv_sum.markdown": " ### MV_SUM Convertit un champ à valeurs multiples en un champ à valeur unique comprenant la somme de toutes les valeurs. ``` ROW a=[3, 5, 6] | EVAL sum_a = MV_SUM(a) ```", "languageDocumentation.documentationESQL.mv_zip": "MV_ZIP", "languageDocumentation.documentationESQL.mv_zip.markdown": " ### MV_ZIP Combine les valeurs de deux champs à valeurs multiples avec un délimiteur qui les relie. ``` ROW a = [\"x\", \"y\", \"z\"], b = [\"1\", \"2\"] | EVAL c = mv_zip(a, b, \"-\") | KEEP a, b, c ```", - "languageDocumentation.documentationESQL.mvExpand": "MV_EXPAND", - "languageDocumentation.documentationESQL.mvExpand.markdown": "### MV_EXPAND La commande de traitement \"MV_EXPAND\" développe les champs à valeurs multiples en une ligne par valeur, en dupliquant les autres champs : ``` ROW a=[1,2,3], b=\"b\", j=[\"a\",\"b\"] | MV_EXPAND a ```", + "languageDocumentation.documentationESQL.mv_expand": "MV_EXPAND", + "languageDocumentation.documentationESQL.mv_expand.markdown": "### MV_EXPAND La commande de traitement \"MV_EXPAND\" développe les champs à valeurs multiples en une ligne par valeur, en dupliquant les autres champs : ``` ROW a=[1,2,3], b=\"b\", j=[\"a\",\"b\"] | MV_EXPAND a ```", "languageDocumentation.documentationESQL.now": "NOW", "languageDocumentation.documentationESQL.now.markdown": " ### NOW Renvoie la date et l'heure actuelles. ``` ROW current_date = NOW() ```", "languageDocumentation.documentationESQL.operators": "Opérateurs", @@ -5661,8 +5661,8 @@ "languageDocumentation.documentationESQL.st_ymin.markdown": " ### ST_YMIN Extrait la valeur minimum des coordonnées \"y\" de la géométrie fournie. Si la géométrie est de type \"geo_point\" ou \"geo_shape\", cela équivaut à extraire la valeur \"latitude\" minimale. ``` FROM airport_city_boundaries | WHERE abbrev == \"CPH\" | EVAL envelope = ST_ENVELOPE(city_boundary) | EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope) | KEEP abbrev, airport, xmin, xmax, ymin, ymax ```", "languageDocumentation.documentationESQL.starts_with": "STARTS_WITH", "languageDocumentation.documentationESQL.starts_with.markdown": " ### STARTS_WITH Renvoie une valeur booléenne qui indique si une chaîne de mots-clés débute par une autre chaîne. ``` FROM employees | KEEP last_name | EVAL ln_S = STARTS_WITH(last_name, \"B\") ```", - "languageDocumentation.documentationESQL.statsby": "STATS ... BY", - "languageDocumentation.documentationESQL.statsby.markdown": "### STATS ... BY Utilisez \"STATS ... BY\" pour regrouper les lignes en fonction d'une valeur commune et calculer une ou plusieurs valeurs agrégées sur les lignes regroupées. **Exemples** : ``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` Si \"BY\" est omis, la table de sortie contient exactement une ligne avec les agrégations appliquées à l'ensemble de données : ``` FROM employees | STATS avg_lang = AVG(languages) ``` Il est possible de calculer plusieurs valeurs : ``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` Il est également possible de regrouper par plusieurs valeurs (uniquement pris en charge pour les champs longs et les familles de mots clés) : ``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long ``` Consultez les **Fonctions d'agrégation** pour obtenir une liste des fonctions qui peuvent être utilisées avec \"STATS... BY\". Les fonctions d'agrégation et les expressions de regroupement acceptent toutes deux d'autres fonctions. Ceci est utile pour utiliser \"STATS...BY\" sur des colonnes à valeur multiple. Par exemple, pour calculer la variation moyenne du salaire, vous pouvez utiliser \"MV_AVG\" pour d'abord faire la moyenne des multiples valeurs par employé, et utiliser le résultat avec la fonction \"AVG\" : ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` Un exemple de regroupement par une expression est le regroupement des employés sur la première lettre de leur nom de famille : ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` La spécification du nom de la colonne de sortie est facultative. S'il n'est pas spécifié, le nouveau nom de la colonne est égal à l'expression. La requête suivante renvoie une colonne nommée \"AVG(salary)\" : ``` FROM employees | STATS AVG(salary) ``` Comme ce nom contient des caractères spéciaux, il doit être entre guillemets inverses (`) lorsque vous l'utilisez dans les commandes suivantes : ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **Note** : \"STATS\" sans groupe est beaucoup plus rapide que l'ajout d'un groupe. **Remarque** : Le regroupement sur une seule expression est actuellement beaucoup plus optimisé que le regroupement sur plusieurs expressions.", + "languageDocumentation.documentationESQL.stats": "STATS ... BY", + "languageDocumentation.documentationESQL.stats.markdown": "### STATS ... BY Utilisez \"STATS ... BY\" pour regrouper les lignes en fonction d'une valeur commune et calculer une ou plusieurs valeurs agrégées sur les lignes regroupées. **Exemples** : ``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` Si \"BY\" est omis, la table de sortie contient exactement une ligne avec les agrégations appliquées à l'ensemble de données : ``` FROM employees | STATS avg_lang = AVG(languages) ``` Il est possible de calculer plusieurs valeurs : ``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` Il est également possible de regrouper par plusieurs valeurs (uniquement pris en charge pour les champs longs et les familles de mots clés) : ``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long ``` Consultez les **Fonctions d'agrégation** pour obtenir une liste des fonctions qui peuvent être utilisées avec \"STATS... BY\". Les fonctions d'agrégation et les expressions de regroupement acceptent toutes deux d'autres fonctions. Ceci est utile pour utiliser \"STATS...BY\" sur des colonnes à valeur multiple. Par exemple, pour calculer la variation moyenne du salaire, vous pouvez utiliser \"MV_AVG\" pour d'abord faire la moyenne des multiples valeurs par employé, et utiliser le résultat avec la fonction \"AVG\" : ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` Un exemple de regroupement par une expression est le regroupement des employés sur la première lettre de leur nom de famille : ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` La spécification du nom de la colonne de sortie est facultative. S'il n'est pas spécifié, le nouveau nom de la colonne est égal à l'expression. La requête suivante renvoie une colonne nommée \"AVG(salary)\" : ``` FROM employees | STATS AVG(salary) ``` Comme ce nom contient des caractères spéciaux, il doit être entre guillemets inverses (`) lorsque vous l'utilisez dans les commandes suivantes : ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **Note** : \"STATS\" sans groupe est beaucoup plus rapide que l'ajout d'un groupe. **Remarque** : Le regroupement sur une seule expression est actuellement beaucoup plus optimisé que le regroupement sur plusieurs expressions.", "languageDocumentation.documentationESQL.std_dev": "STD_DEV", "languageDocumentation.documentationESQL.std_dev.markdown": " ### STD_DEV La déviation standard d'un champ numérique. ``` FROM employees | STATS STD_DEV(height) ```", "languageDocumentation.documentationESQL.substring": "SUBSTRING", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 37eb10a2b4a9f..14d362b5587a0 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -5531,8 +5531,8 @@ "languageDocumentation.documentationESQL.log.markdown": " ### LOG 基数に対する値の対数を返します。入力は任意の数値で、戻り値は常にdoubleです。ゼロの対数、負数、1の基数はnullと警告を返します。``` ROW base = 2.0, value = 8.0 | EVAL s = LOG(base, value) ```", "languageDocumentation.documentationESQL.log10": "LOG10", "languageDocumentation.documentationESQL.log10.markdown": " ### LOG10 基数10に対する値の対数を返します。入力は任意の数値で、戻り値は常にdoubleです。0の対数および負数はnullと警告を返します。``` ROW d = 1000.0 | EVAL s = LOG10(d) ```", - "languageDocumentation.documentationESQL.lookupJoin": "LOOKUP JOIN", - "languageDocumentation.documentationESQL.lookupJoin.markdown": "### LOOKUP JOIN LOOKUP JOINを使用して、既存のインデックスから受信行にデータを追加できます。これはENRICHに似ていますが、事前にエンリッチポリシーを実行する必要はありません。さらに、ルックアップインデックスで複数の一致するドキュメントが見つかった場合、複数の出力行が生成されます。``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` LOOKUP JOINで使用されるインデックスは、ルックアップモードにする必要があります。この[インデックスモード](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings)は、インデックス作成時に設定する必要があります。``` PUT languages '{ \"settings\": { \"index\":{ \"mode\":\"lookup\" } } }' ``` 結合キーフィールドは、互換性のある型でなければならず、一致するドキュメントを検索するには、ルックアップインデックス内のフィールド名と一致する必要があります。必要に応じて、RENAMEまたはEVALを使用して列の名前を変更できます。``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` 名前が競合する場合は、ルックアップインデックスのフィールドが既存のフィールドを上書きします。", + "languageDocumentation.documentationESQL.lookup": "LOOKUP JOIN", + "languageDocumentation.documentationESQL.lookup.markdown": "### LOOKUP JOIN LOOKUP JOINを使用して、既存のインデックスから受信行にデータを追加できます。これはENRICHに似ていますが、事前にエンリッチポリシーを実行する必要はありません。さらに、ルックアップインデックスで複数の一致するドキュメントが見つかった場合、複数の出力行が生成されます。``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` LOOKUP JOINで使用されるインデックスは、ルックアップモードにする必要があります。この[インデックスモード](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings)は、インデックス作成時に設定する必要があります。``` PUT languages '{ \"settings\": { \"index\":{ \"mode\":\"lookup\" } } }' ``` 結合キーフィールドは、互換性のある型でなければならず、一致するドキュメントを検索するには、ルックアップインデックス内のフィールド名と一致する必要があります。必要に応じて、RENAMEまたはEVALを使用して列の名前を変更できます。``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` 名前が競合する場合は、ルックアップインデックスのフィールドが既存のフィールドを上書きします。", "languageDocumentation.documentationESQL.ltrim": "LTRIM", "languageDocumentation.documentationESQL.ltrim.markdown": " ### LTRIM 文字列から先頭の空白を取り除きます。``` ROW message = \" some text \", color = \" red \" | EVAL message = LTRIM(message) | EVAL color = LTRIM(color) | EVAL message = CONCAT(\"'\", message, \"'\") | EVAL color = CONCAT(\"'\", color, \"'\") ```", "languageDocumentation.documentationESQL.markdown": "ES|QL(Elasticsearch クエリー言語)クエリーは、パイプ文字の|で区切られた一連のコマンドで構成されます。各クエリーは**ソースコマンド**で始まり、通常はElasticsearchのデータを使ってテーブルを生成します。ソースコマンドには、1つ以上の**処理コマンド**を続けることができます。処理コマンドは、行や列を追加、削除、変更することで、前のコマンドの出力テーブルを変更することができます。``` source-command | processing-command1 | processing-command2 ```クエリの結果は、最終的な処理コマンドによって生成されるテーブルです。", @@ -5582,8 +5582,8 @@ "languageDocumentation.documentationESQL.mv_sum.markdown": " ### MV_SUM は、複数値フィールドを、すべての値の合計を含む単一値フィールドに変換します。``` ROW a=[3, 5, 6] | EVAL sum_a = MV_SUM(a) ```", "languageDocumentation.documentationESQL.mv_zip": "MV_ZIP", "languageDocumentation.documentationESQL.mv_zip.markdown": " ### MV_ZIP 値を結合する区切り文字を使用して、2つの複数値フィールドの値を結合します。``` ROW a = [\"x\", \"y\", \"z\"], b = [\"1\", \"2\"] | EVAL c = mv_zip(a, b, \"-\") | KEEP a, b, c ```", - "languageDocumentation.documentationESQL.mvExpand": "MV_EXPAND", - "languageDocumentation.documentationESQL.mvExpand.markdown": "### MV_EXPAND `MV_EXPAND`処理コマンドは、複数値フィールドを値ごとに1行に展開し、他のフィールドを複製します。 ``` ROW a=[1,2,3], b=\"b\", j=[\"a\",\"b\"] | MV_EXPAND a ```", + "languageDocumentation.documentationESQL.mv_expand": "MV_EXPAND", + "languageDocumentation.documentationESQL.mv_expand.markdown": "### MV_EXPAND `MV_EXPAND`処理コマンドは、複数値フィールドを値ごとに1行に展開し、他のフィールドを複製します。 ``` ROW a=[1,2,3], b=\"b\", j=[\"a\",\"b\"] | MV_EXPAND a ```", "languageDocumentation.documentationESQL.now": "NOW", "languageDocumentation.documentationESQL.now.markdown": " ### NOW 現在の日付と時刻を返します。``` ROW current_date = NOW() ```", "languageDocumentation.documentationESQL.operators": "演算子", @@ -5664,8 +5664,8 @@ "languageDocumentation.documentationESQL.st_ymin.markdown": " ### ST_YMIN 指定されたジオメトリから、y座標の最小値を抽出します。ジオメトリ型がgeo_pointまたはgeo_shapeの場合、これは最小latitude値を抽出することと同じです。``` FROM airport_city_boundaries | WHERE abbrev == \"CPH\" | EVAL envelope = ST_ENVELOPE(city_boundary) | EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope) | KEEP abbrev, airport, xmin, xmax, ymin, ymax ```", "languageDocumentation.documentationESQL.starts_with": "STARTS_WITH", "languageDocumentation.documentationESQL.starts_with.markdown": " ### STARTS_WITH キーワード文字列が別の文字列で始まるかどうかを示すブール値を返します。``` FROM employees | KEEP last_name | EVAL ln_S = STARTS_WITH(last_name, \"B\") ```", - "languageDocumentation.documentationESQL.statsby": "STATS ...BY", - "languageDocumentation.documentationESQL.statsby.markdown": "### STATS ... BY BYを使用すると、共通の値に従って行をグループ化し、グループ化された行に対する1つ以上の集約値を計算します。**例**: ``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` BYが省略された場合、出力テーブルには、データセット全体に適用された集約が正確に1行だけ含まれます。 ``` FROM employees | STATS avg_lang = AVG(languages) ``` 複数の値を計算することができます。 ``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` 複数の値でグループ化することも可能です(longおよびkeywordファミリーフィールドでのみサポート)。 ``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long ``` STATS ...BYで使用できる関数の一覧については、**集計関数**を参照してください。集計関数とグループ式の両方で他の関数を使用できます。これは、複数値列でSTATS...BYを使用するときに有用です。たとえば、平均給与変動を計算するには、まず、MV_AVGを使用して従業員ごとに複数の値の平均を求め、その結果にAVG関数を適用します。 ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` 式によるグループ化の例は、姓の最初の文字で従業員をグループ化することです。 ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` 出力列名の指定は任意です。指定しない場合は、新しい列名が式と等しくなります。次のクエリーは列\"AVG(salary)\"を返します。 ``` FROM employees | STATS AVG(salary) ``` この名前には特殊文字が含まれているため、後続のコマンドで使用するときには、バッククオート(`)で囲む必要があります。 ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **注**:グループなしのSTATSは、グループを追加するよりも大幅に高速です。**注**: 単一式でのグループは、現在、複数式でのグループよりも大幅に最適化されています。", + "languageDocumentation.documentationESQL.stats": "STATS ...BY", + "languageDocumentation.documentationESQL.stats.markdown": "### STATS ... BY BYを使用すると、共通の値に従って行をグループ化し、グループ化された行に対する1つ以上の集約値を計算します。**例**: ``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` BYが省略された場合、出力テーブルには、データセット全体に適用された集約が正確に1行だけ含まれます。 ``` FROM employees | STATS avg_lang = AVG(languages) ``` 複数の値を計算することができます。 ``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` 複数の値でグループ化することも可能です(longおよびkeywordファミリーフィールドでのみサポート)。 ``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long ``` STATS ...BYで使用できる関数の一覧については、**集計関数**を参照してください。集計関数とグループ式の両方で他の関数を使用できます。これは、複数値列でSTATS...BYを使用するときに有用です。たとえば、平均給与変動を計算するには、まず、MV_AVGを使用して従業員ごとに複数の値の平均を求め、その結果にAVG関数を適用します。 ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` 式によるグループ化の例は、姓の最初の文字で従業員をグループ化することです。 ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` 出力列名の指定は任意です。指定しない場合は、新しい列名が式と等しくなります。次のクエリーは列\"AVG(salary)\"を返します。 ``` FROM employees | STATS AVG(salary) ``` この名前には特殊文字が含まれているため、後続のコマンドで使用するときには、バッククオート(`)で囲む必要があります。 ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **注**:グループなしのSTATSは、グループを追加するよりも大幅に高速です。**注**: 単一式でのグループは、現在、複数式でのグループよりも大幅に最適化されています。", "languageDocumentation.documentationESQL.std_dev": "STD_DEV", "languageDocumentation.documentationESQL.std_dev.markdown": " ### STD_DEV 数値フィールドの標準偏差。``` FROM employees | STATS STD_DEV(height) ```", "languageDocumentation.documentationESQL.substring": "SUBSTRING", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 38fe2740379d2..40c3f3c178bc6 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -5523,8 +5523,8 @@ "languageDocumentation.documentationESQL.log.markdown": " ### LOG 返回以某数为底数时某个值的对数。输入可以为任何数字值,返回值始终为双精度值。求零、负数的对数,以及底数为一时将返回 `null`,并显示警告。```ROW base = 2.0,value = 8.0 | EVAL s = LOG(base, value)```", "languageDocumentation.documentationESQL.log10": "LOG10", "languageDocumentation.documentationESQL.log10.markdown": " ### LOG10 返回以 10 为底数时某个值的对数。输入可以为任何数字值,返回值始终为双精度值。求 0 和负数的对数时将返回 `null`,并显示警告。``` ROW d = 1000.0 | EVAL s = LOG10(d) ```", - "languageDocumentation.documentationESQL.lookupJoin": "LOOKUP JOIN", - "languageDocumentation.documentationESQL.lookupJoin.markdown": "### LOOKUP JOIN 您可以使用 `LOOKUP JOIN` 将现有索引中的数据添加到传入行。虽然此函数与 `ENRICH` 类似,但它不需要事先执行扩充策略。此外,如果在查找索引中找到多个匹配文档,它们将生成多个输出行。``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` `LOOKUP JOIN` 中使用的索引需要处于查找模式。此 [索引模式](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings)需要在创建索引时设置。``` PUT languages '{ “settings”: { “index”:{ \"mode\":\"lookup\" } } }' ``` 联接键字段必须具有兼容的类型,并与查找索引中的字段名称匹配,才能查找匹配的文档。可以根据需要使用 `RENAME` 或 `EVAL` 来重命名列。``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` 如果出现名称冲突,来自查找索引的字段将覆盖现有字段。", + "languageDocumentation.documentationESQL.lookup": "LOOKUP JOIN", + "languageDocumentation.documentationESQL.lookup.markdown": "### LOOKUP JOIN 您可以使用 `LOOKUP JOIN` 将现有索引中的数据添加到传入行。虽然此函数与 `ENRICH` 类似,但它不需要事先执行扩充策略。此外,如果在查找索引中找到多个匹配文档,它们将生成多个输出行。``` ROW language_code = 1 | LOOKUP JOIN languages ON language_code ``` `LOOKUP JOIN` 中使用的索引需要处于查找模式。此 [索引模式](https://www.elastic.co/docs/reference/elasticsearch/index-settings/index-modules#_static_index_settings)需要在创建索引时设置。``` PUT languages '{ “settings”: { “index”:{ \"mode\":\"lookup\" } } }' ``` 联接键字段必须具有兼容的类型,并与查找索引中的字段名称匹配,才能查找匹配的文档。可以根据需要使用 `RENAME` 或 `EVAL` 来重命名列。``` FROM employees | EVAL language_code = languages | LOOKUP JOIN languages ON language_code ``` 如果出现名称冲突,来自查找索引的字段将覆盖现有字段。", "languageDocumentation.documentationESQL.ltrim": "LTRIM", "languageDocumentation.documentationESQL.ltrim.markdown": " ### LTRIM 从字符串中删除前导空格。``` ROW message = \" some text \", color = \" red \" | EVAL message = LTRIM(message) | EVAL color = LTRIM(color) | EVAL message = CONCAT(\"'\", message, \"'\") | EVAL color = CONCAT(\"'\", color, \"'\") ```", "languageDocumentation.documentationESQL.markdown": "ES|QL(Elasticsearch 查询语言)查询包含一系列命令,它们用管道字符分隔:`|`。每个查询以**源命令**开头,它会生成一个表,其中通常包含来自 Elasticsearch 的数据。源命令可后接一个或多个**处理命令**。处理命令可通过添加、移除以及更改行和列来更改前一个命令的输出表。``` source-command | processing-command1 | processing-command2 ```查询的结果为由最后的处理命令生成的表。", @@ -5574,8 +5574,8 @@ "languageDocumentation.documentationESQL.mv_sum.markdown": " ### MV_SUM 将多值字段转换为包含所有值的总和的单值字段。``` ROW a=[3, 5, 6] | EVAL sum_a = MV_SUM(a) ```", "languageDocumentation.documentationESQL.mv_zip": "MV_ZIP", "languageDocumentation.documentationESQL.mv_zip.markdown": " ### MV_ZIP 使用分隔符将两个多值字段中的值合并起来,分隔符的作用是将值联接在一起。``` ROW a = [\"x\", \"y\", \"z\"], b = [\"1\", \"2\"] | EVAL c = mv_zip(a, b, \"-\") | 保留 a, b, c ```", - "languageDocumentation.documentationESQL.mvExpand": "MV_EXPAND", - "languageDocumentation.documentationESQL.mvExpand.markdown": "### MV_EXPAND `MV_EXPAND` 处理命令将多值字段扩展为每个值一行,并复制其他字段: ``` ROW a=[1,2,3],b=\"b\",j=[\"a\",\"b\"] | MV_EXPAND a ```", + "languageDocumentation.documentationESQL.mv_expand": "MV_EXPAND", + "languageDocumentation.documentationESQL.mv_expand.markdown": "### MV_EXPAND `MV_EXPAND` 处理命令将多值字段扩展为每个值一行,并复制其他字段: ``` ROW a=[1,2,3],b=\"b\",j=[\"a\",\"b\"] | MV_EXPAND a ```", "languageDocumentation.documentationESQL.now": "NOW", "languageDocumentation.documentationESQL.now.markdown": " ### NOW 返回当前日期和时间。 ``` ROW current_date = NOW() ```", "languageDocumentation.documentationESQL.operators": "运算符", @@ -5656,8 +5656,8 @@ "languageDocumentation.documentationESQL.st_ymin.markdown": " ### ST_YMIN 从提供的几何图形中提取 `y` 坐标的最小值。如果几何图形的类型为 `geo_point` 或 `geo_shape`,则这等同于提取最小 `latitude` 值。``` FROM airport_city_boundaries | WHERE abbrev == \"CPH\" | EVAL envelope = ST_ENVELOPE(city_boundary) | EVAL xmin = ST_XMIN(envelope), xmax = ST_XMAX(envelope), ymin = ST_YMIN(envelope), ymax = ST_YMAX(envelope) | KEEP abbrev, airport, xmin, xmax, ymin, ymax ```", "languageDocumentation.documentationESQL.starts_with": "STARTS_WITH", "languageDocumentation.documentationESQL.starts_with.markdown": " ### STARTS_WITH 返回一个布尔值,指示关键字字符串是否以另一个字符串开头。``` FROM employees | KEEP last_name | EVAL ln_S = STARTS_WITH(last_name, \"B\") ```", - "languageDocumentation.documentationESQL.statsby": "STATS ...BY", - "languageDocumentation.documentationESQL.statsby.markdown": "### STATS ... BY 使用 `STATS ... BY` 可根据公共值对行分组,并计算已分组行中的一个或多个聚合值。**示例**:``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` 如果省略 \"BY\",输出表将只包含一条记录,并对整个数据集进行聚合:``` FROM employees | STATS avg_lang = AVG(languages) ``` 可以计算多个值:``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` 还可以按多个值分组(仅支持长字段和关键字族字段):``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long `` 有关可与 `STATS ... BY` 一起使用的函数列表,请参阅**聚合函数**。聚合函数和分组表达式均接受其他函数。这在对多值列使用 `STATS...BY` 时有用。例如,要计算平均工资变化,可以使用 `MV_AVG` 首先对每个员工的多个值求平均值,然后将结果与 `AVG` 函数一起使用: ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` 通过表达式分组的一个示例是按员工姓氏的首字母对员工进行分组: ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` 指定输出列名是可选的。如果未指定,新列名称等于该表达式。以下查询返回名为 `AVG(salary)` 的列: ``` FROM employees | STATS AVG(salary) ``` 由于此名称包含特殊字符,因此在后续命令中使用它时需要用反引号 (`) 引起来: ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **注意**:没有任何组的 `STATS` 比添加组要快得多。**注意**:当前,根据单一表达式进行分组比根据许多表达式进行分组更为优化。", + "languageDocumentation.documentationESQL.stats": "STATS ...BY", + "languageDocumentation.documentationESQL.stats.markdown": "### STATS ... BY 使用 `STATS ... BY` 可根据公共值对行分组,并计算已分组行中的一个或多个聚合值。**示例**:``` FROM employees | STATS count = COUNT(emp_no) BY languages | SORT languages ``` 如果省略 \"BY\",输出表将只包含一条记录,并对整个数据集进行聚合:``` FROM employees | STATS avg_lang = AVG(languages) ``` 可以计算多个值:``` FROM employees | STATS avg_lang = AVG(languages), max_lang = MAX(languages) ``` 还可以按多个值分组(仅支持长字段和关键字族字段):``` FROM employees | EVAL hired = DATE_FORMAT(hire_date, \"YYYY\") | STATS avg_salary = AVG(salary) BY hired, languages.long | EVAL avg_salary = ROUND(avg_salary) | SORT hired, languages.long `` 有关可与 `STATS ... BY` 一起使用的函数列表,请参阅**聚合函数**。聚合函数和分组表达式均接受其他函数。这在对多值列使用 `STATS...BY` 时有用。例如,要计算平均工资变化,可以使用 `MV_AVG` 首先对每个员工的多个值求平均值,然后将结果与 `AVG` 函数一起使用: ``` FROM employees | STATS avg_salary_change = AVG(MV_AVG(salary_change)) ``` 通过表达式分组的一个示例是按员工姓氏的首字母对员工进行分组: ``` FROM employees | STATS my_count = COUNT() BY LEFT(last_name, 1) | SORT `LEFT(last_name, 1)` ``` 指定输出列名是可选的。如果未指定,新列名称等于该表达式。以下查询返回名为 `AVG(salary)` 的列: ``` FROM employees | STATS AVG(salary) ``` 由于此名称包含特殊字符,因此在后续命令中使用它时需要用反引号 (`) 引起来: ``` FROM employees | STATS AVG(salary) | EVAL avg_salary_rounded = ROUND(`AVG(salary)`) ``` **注意**:没有任何组的 `STATS` 比添加组要快得多。**注意**:当前,根据单一表达式进行分组比根据许多表达式进行分组更为优化。", "languageDocumentation.documentationESQL.std_dev": "STD_DEV", "languageDocumentation.documentationESQL.std_dev.markdown": " ### STD_DEV 数值字段的标准偏差。``` FROM employees | STATS STD_DEV(height) ```", "languageDocumentation.documentationESQL.substring": "SUBSTRING",