Skip to content
SOC FluentSpeak SIEM and EDR

For Elastic Security and Kibana

Elastic KQL and ES|QL cheat sheet

Elastic has two query languages. Kibana KQL filters events in the search bar. ES|QL is a full piped language that can also count, group and reshape. Both are on this page, with the field names you need.

Checked against Elastic’s documentation in November 2026.

Kibana KQL

For the search bar in Discover and Elastic Security. It only filters. Set the time range with the time picker.

To do thisWrite this
Match a valueOn keyword fields, case and punctuation must match exactly.
process.name : "cmd.exe"
Any of several values
process.name : ("cmd.exe" or "powershell.exe")
Both conditions
host.name : "ws01" and event.code : "4625"
Exclude a value
not process.name : "explorer.exe"
WildcardOnly * is supported. Inside quotes it’s a plain asterisk.
process.name : power*
Field has a value
user.name : *
Range
destination.port < 1024
Group conditions
(event.code : "4624" or event.code : "4625") and user.name : "admin"

ES|QL

For Discover in ES|QL mode, Elastic Security and detection rules. Each line after FROM starts with a pipe.

To do thisWrite this
Start from an index
FROM logs-*
Last 24 hours
| WHERE @timestamp > NOW() - 24 hours
Exact match
| WHERE process.name == "cmd.exe"
Ignore case
| WHERE TO_LOWER(process.name) == "cmd.exe"
One of several
| WHERE process.name IN ("cmd.exe", "powershell.exe")
Wildcard match* is any text and ? is one character. Case-sensitive.
| WHERE process.command_line LIKE "*-enc*"
Regex match
| WHERE process.command_line RLIKE ".*https?://.*"
Has a value
| WHERE user.name IS NOT NULL
Keep only these columns
| KEEP @timestamp, host.name, process.command_line
Drop a column
| DROP event.original
Rename a column
| RENAME host.name AS host
Add a calculated column
| EVAL exe = TO_LOWER(process.name)
Count by a column
| STATS runs = COUNT(*) BY host.name
Count distinct valuesAn estimate. It can be slightly off on large data.
| STATS hosts = COUNT_DISTINCT(host.name) BY process.name
Count per hour
| STATS events = COUNT(*) BY hour = BUCKET(@timestamp, 1 hour)
First and last seen
| STATS first_seen = MIN(@timestamp), last_seen = MAX(@timestamp) BY host.name
Sort
| SORT runs DESC
Limit the rowsWith no LIMIT you get 1,000 rows. The most is 10,000.
| LIMIT 10
Split text with a pattern
| DISSECT message "%{user} logged in from %{ip}"
Pull text out with grok
| GROK message "%{IP:source_ip}"
One row per value
| MV_EXPAND process.args

Common field names

Elastic Security uses the Elastic Common Schema (ECS). These names are the same in Kibana KQL and ES|QL.

To do thisWrite this
Process name
process.name
Command line
process.command_line
Parent process
process.parent.name
Path to the program
process.executable
Computer name
host.name
User name
user.name
Windows event ID
event.code
Source and destination IP
source.ip, destination.ip
Destination port
destination.port
File path
file.path

Watch out for

  • Kibana KQL is not Microsoft’s KQL. They share a name and nothing else.
  • Kibana KQL only filters. To count or group, switch to ES|QL.
  • Keyword values are case-sensitive, and the Kibana search bar can’t ignore case. In ES|QL, use TO_LOWER().
  • In ES|QL, comparing a field that holds several values, like == or >, gives null, so the row is dropped. Use MV_EXPAND first.
  • ES|QL returns 1,000 rows unless you add LIMIT, and never more than 10,000.
  • A leading wildcard like *shell.exe works by default, but an admin can turn it off.

Keep going

Practise these in real exercises

A cheat sheet tells you the syntax. SOC Fluent gives you exercises to solve with it, on realistic lab data, and shows you what your query missed. Join the waitlist and we’ll email you once, on launch day.

Free to join. Students get 50% off at launch.