mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ES|QL] More run query helpers (#183906)
## Summary Part of https://github.com/elastic/kibana/issues/179641 Adds another run query helper based on the search strategy in our esql-utils package.
This commit is contained in:
parent
66182b451b
commit
96b195b76c
4 changed files with 89 additions and 72 deletions
|
@ -18,6 +18,7 @@ export {
|
|||
appendWhereClauseToESQLQuery,
|
||||
getESQLQueryColumns,
|
||||
getESQLQueryColumnsRaw,
|
||||
getESQLResults,
|
||||
TextBasedLanguages,
|
||||
} from './src';
|
||||
|
||||
|
|
|
@ -16,4 +16,4 @@ export {
|
|||
removeDropCommandsFromESQLQuery,
|
||||
} from './utils/query_parsing_helpers';
|
||||
export { appendToESQLQuery, appendWhereClauseToESQLQuery } from './utils/append_to_query';
|
||||
export { getESQLQueryColumns, getESQLQueryColumnsRaw } from './utils/run_query';
|
||||
export { getESQLQueryColumns, getESQLQueryColumnsRaw, getESQLResults } from './utils/run_query';
|
||||
|
|
|
@ -9,58 +9,23 @@ import { i18n } from '@kbn/i18n';
|
|||
import type { DatatableColumn } from '@kbn/expressions-plugin/common';
|
||||
import type { ISearchGeneric } from '@kbn/search-types';
|
||||
import { esFieldTypeToKibanaFieldType } from '@kbn/field-types';
|
||||
import type { ESQLColumn, ESQLSearchReponse } from '@kbn/es-types';
|
||||
import type { ESQLColumn, ESQLSearchReponse, ESQLSearchParams } from '@kbn/es-types';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { ESQL_LATEST_VERSION } from '../../constants';
|
||||
|
||||
export async function getESQLQueryColumns({
|
||||
esqlQuery,
|
||||
search,
|
||||
signal,
|
||||
}: {
|
||||
esqlQuery: string;
|
||||
search: ISearchGeneric;
|
||||
signal?: AbortSignal;
|
||||
}): Promise<DatatableColumn[]> {
|
||||
try {
|
||||
const response = await lastValueFrom(
|
||||
search(
|
||||
{
|
||||
params: {
|
||||
query: `${esqlQuery} | limit 0`,
|
||||
version: ESQL_LATEST_VERSION,
|
||||
},
|
||||
},
|
||||
{
|
||||
abortSignal: signal,
|
||||
strategy: 'esql_async',
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
const columns =
|
||||
(response.rawResponse as unknown as ESQLSearchReponse).columns?.map(({ name, type }) => {
|
||||
const kibanaType = esFieldTypeToKibanaFieldType(type);
|
||||
const column = {
|
||||
id: name,
|
||||
name,
|
||||
meta: { type: kibanaType, esType: type },
|
||||
} as DatatableColumn;
|
||||
|
||||
return column;
|
||||
}) ?? [];
|
||||
|
||||
return columns;
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
i18n.translate('esqlUtils.columnsErrorMsg', {
|
||||
defaultMessage: 'Unable to load columns. {errorMessage}',
|
||||
values: { errorMessage: error.message },
|
||||
})
|
||||
);
|
||||
}
|
||||
export function formatESQLColumns(columns: ESQLColumn[]): DatatableColumn[] {
|
||||
return columns.map(({ name, type }) => {
|
||||
const kibanaType = esFieldTypeToKibanaFieldType(type);
|
||||
return {
|
||||
id: name,
|
||||
name,
|
||||
meta: { type: kibanaType, esType: type },
|
||||
} as DatatableColumn;
|
||||
});
|
||||
}
|
||||
|
||||
// Returns the columns exactly as being returned by the _query endpoint
|
||||
// Based on the search api from the data plugin
|
||||
export async function getESQLQueryColumnsRaw({
|
||||
esqlQuery,
|
||||
search,
|
||||
|
@ -96,3 +61,69 @@ export async function getESQLQueryColumnsRaw({
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the columns with the kibana format
|
||||
// Based on the search api from the data plugin
|
||||
export async function getESQLQueryColumns({
|
||||
esqlQuery,
|
||||
search,
|
||||
signal,
|
||||
}: {
|
||||
esqlQuery: string;
|
||||
search: ISearchGeneric;
|
||||
signal?: AbortSignal;
|
||||
}): Promise<DatatableColumn[]> {
|
||||
try {
|
||||
const rawColumns = await getESQLQueryColumnsRaw({ esqlQuery, search, signal });
|
||||
const columns = formatESQLColumns(rawColumns) ?? [];
|
||||
|
||||
return columns;
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
i18n.translate('esqlUtils.columnsErrorMsg', {
|
||||
defaultMessage: 'Unable to load columns. {errorMessage}',
|
||||
values: { errorMessage: error.message },
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the table as being returned by the _query endpoint
|
||||
// Based on the search api from the data plugin
|
||||
export async function getESQLResults({
|
||||
esqlQuery,
|
||||
search,
|
||||
signal,
|
||||
filter,
|
||||
dropNullColumns,
|
||||
}: {
|
||||
esqlQuery: string;
|
||||
search: ISearchGeneric;
|
||||
signal?: AbortSignal;
|
||||
filter?: unknown;
|
||||
dropNullColumns?: boolean;
|
||||
}): Promise<{
|
||||
response: ESQLSearchReponse;
|
||||
params: ESQLSearchParams;
|
||||
}> {
|
||||
const result = await lastValueFrom(
|
||||
search(
|
||||
{
|
||||
params: {
|
||||
...(filter ? { filter } : {}),
|
||||
query: esqlQuery,
|
||||
version: ESQL_LATEST_VERSION,
|
||||
...(dropNullColumns ? { dropNullColumns: true } : {}),
|
||||
},
|
||||
},
|
||||
{
|
||||
abortSignal: signal,
|
||||
strategy: 'esql_async',
|
||||
}
|
||||
)
|
||||
);
|
||||
return {
|
||||
response: result.rawResponse as unknown as ESQLSearchReponse,
|
||||
params: result.requestParams as unknown as ESQLSearchParams,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import type { IKibanaSearchResponse, IKibanaSearchRequest } from '@kbn/search-types';
|
||||
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import type { ESQLSearchParams, ESQLSearchReponse } from '@kbn/es-types';
|
||||
import type { AggregateQuery } from '@kbn/es-query';
|
||||
import { ESQL_LATEST_VERSION, getESQLWithSafeLimit } from '@kbn/esql-utils';
|
||||
import { getESQLWithSafeLimit, getESQLResults } from '@kbn/esql-utils';
|
||||
import type { FieldStatsResponse } from '../../types';
|
||||
import {
|
||||
buildSearchFilter,
|
||||
|
@ -63,27 +60,15 @@ export const loadFieldStatsTextBased: LoadFieldStatsTextBasedHandler = async ({
|
|||
return {};
|
||||
}
|
||||
|
||||
const searchHandler: SearchHandlerTextBased = async (body) => {
|
||||
const searchHandler: SearchHandlerTextBased = async ({ query }) => {
|
||||
const filter = buildSearchFilter({ timeFieldName: dataView.timeFieldName, fromDate, toDate });
|
||||
const result = await lastValueFrom(
|
||||
data.search.search<
|
||||
IKibanaSearchRequest<ESQLSearchParams>,
|
||||
IKibanaSearchResponse<ESQLSearchReponse>
|
||||
>(
|
||||
{
|
||||
params: {
|
||||
...(filter ? { filter } : {}),
|
||||
...body,
|
||||
version: ESQL_LATEST_VERSION,
|
||||
},
|
||||
},
|
||||
{
|
||||
abortSignal: abortController?.signal,
|
||||
strategy: 'esql',
|
||||
}
|
||||
)
|
||||
);
|
||||
return result.rawResponse;
|
||||
const result = await getESQLResults({
|
||||
esqlQuery: query,
|
||||
filter,
|
||||
search: data.search.search,
|
||||
signal: abortController?.signal,
|
||||
});
|
||||
return result.response;
|
||||
};
|
||||
|
||||
if (!('esql' in baseQuery)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue