src/platform/packages/shared/kbn-esql-composer/README.md
[!WARNING] This package is deprecated and will be removed in a future version. Please migrate to the Composer API in
@elastic/esql. See: https://github.com/elastic/esql-js/blob/main/src/composer/README.md
This package provides a high-level, functional ESQL composer for safely and programmatically building Elasticsearch queries. It serves as a user-friendly abstraction over the @kbn/esql-language package.
This ESQL composer is designed to be used by importing individual command functions (from, where, stats, etc.) and chaining them together to form a query pipeline.
A query starts by invoking a source command like from(), which returns a QueryPipeline. This pipeline can be extended through .pipe(...) calls and rendered as a string with .toString() or request object with asRequest.
import { from, where, sort, keep, limit, SortOrder } from '@kbn/esql-composer';
const query = from('logs-*')
.pipe(
where('@timestamp >= NOW() - 1 hour'),
sort({ '@timestamp': SortOrder.Desc }),
keep('service.name', 'log.level'),
limit(10)
)
.toString();
The above example will output
FROM logs-*
| WHERE @timestamp >= NOW() - 1 hour
| SORT @timestamp DESC
| KEEP service.name, log.level
| LIMIT 10
import { from, where, sort, keep, limit, SortOrder } from '@kbn/esql-composer';
const query = from('logs-*')
.pipe(
where('@timestamp >= NOW() - 1 hour AND service.environment == ?svcEnv', {
svcEnv: 'production'
}),
sort({ '@timestamp': SortOrder.Desc }),
keep('service.name', 'log.level'),
limit(10)
)
.asRequest();
The above example will output
{
query: `FROM logs-*
| WHERE @timestamp >= NOW() - 1 hour AND service.environment == ?svcEnv
| SORT @timestamp DESC
| KEEP service.name, log.level
| LIMIT 10
`,
params: [{ svcEnv: 'production' }]
}
import { from, where, sort, keep, limit, SortOrder } from '@kbn/esql-composer';
const limitReturnedFields = req.query('limitReturnedFields')
let pipelipine = from('logs-*').pipe(
where('@timestamp <= NOW() AND @timestamp > NOW() - 24 hours'),
limit(10s)
);
if (limitReturnedFields) {
pipeline = pipeline.pipe(keep('@timestamp', 'service.name'))
}
pipeline.toString()
// OR
let pipelipine = from('logs-*').pipe(
where('@timestamp <= NOW() AND @timestamp > NOW() - 24 hours'),
limit(10s)
).pipe(limitReturnedFields ? keep('@timestamp', 'service.name') : (query) => query);
pipeline.toString()
The above example will output
limitReturnedFields is trueFROM logs-*
| WHERE @timestamp >= NOW() - 1 hour
| LIMIT 10
| KEEP @timetsamp, service.name
limitReturnedFields is falseFROM logs-*
| WHERE @timestamp >= NOW() - 1 hour
| LIMIT 10
toString() – outputs the ES|QL query as a readable string.
asRequest() – outputs an object for Elasticsearch’s ES|QL query API, including parameters.
WHEREWHERE clause
import { from, where } from '@kbn/esql-composer';
from('logs-*')
.pipe(where('@timestamp <= NOW() AND @timestamp > NOW() - 24 hours'))
.toString();
Output:
FROM logs-*
| WHERE @timestamp <= NOW() AND @timestamp > NOW() - 24 hours
WHERE with named parametersimport { from, where } from '@kbn/esql-composer';
from('logs-*')
.pipe(where('host.name == ?hostName AND service.name == ?serviceName',
{
hostName: 'my-host',
serviceName: 'my-service'
}
))
.toString();
Output:
FROM logs-*
| WHERE host.name == "my-host" AND service.name == "my-service"
WHERE with positional parametersimport { from, where } from '@kbn/esql-composer';
from('logs-*')
.pipe(where('host.name IN (?,?,?)', ['my-host-1', 'my-host-2', 'my-host-3']))
.toString();
Output:
FROM logs-*
| WHERE host.name IN ("my-host-1", "my-host-2", "my-host-3")
STATSBasic STATS clause
import { from, stats } from '@kbn/esql-composer';
from('logs-*')
.pipe(stats('avg_duration = AVG(transaction.duration.us) BY service.name'))
.toString();
Output:
FROM logs-*
| WHERE avg_duration = AVG(transaction.duration.us) BY service.name
STATS with named parameters for dynamic field and function names
import { from, stats } from '@kbn/esql-composer';
from('logs-*')
.pipe(
stats('??funcName(??duration), COUNT(??svcName) WHERE agent.name == "java" BY ??env', {
funcName: 'AVG',
duration: 'transaction.duration.us',
svcName: 'service.name',
env: 'service.environment',
})
)
.toString();
Returns
FROM logs-*
| STATS AVG(transaction.duration.us), COUNT(service.name) WHERE agent.name == "java" BY sevice.environment
EVALBasic EVAL clause
import { from, evaluate } from '@kbn/esql-composer';
from('logs-*')
.pipe(
evaluate('type = CASE(languages <= 1, "monolingual",languages <= 2, "bilingual","polyglot")')
)
.toString();
Output:
FROM logs-*
| EVAL type = CASE(languages <= 1, "monolingual",languages <= 2, "bilingual","polyglot")
SORTSORT by string fields (ASC by default)
import { from, sort } from '@kbn/esql-composer';
from('logs-*')
.pipe(sort('@timestamp', 'log.level'))
.toString();
Output:
FROM logs-*
| SORT @timestamp, log.level ASC
SORT with explicit order
import { from, evaluate } from '@kbn/esql-composer';
from('logs-*')
.pipe(sort({ '@timestamp': SortOrder.Desc }))
.toString();
Output:
FROM logs-*
| SORT @timestamp DESC
SORT with named parameters
import { from, sort } from '@kbn/esql-composer';
from('logs-*')
.pipe(
sort('??timestamp DESC, ??logLevel ASC', {
timestamp: '@timestamp',
logLevel: 'log.level',
})
)
.toString();
Output:
FROM logs-*
| SORT @timestamp DESC, log.level ASC