```markdown
# ES|QL Syntax Reference

The **Elasticsearch Query Language (ES|QL)** provides a powerful, piped syntax for filtering, transforming, and analyzing data stored in Elasticsearch. ES|QL is designed to be easy to learn and use, supporting a wide range of commands, functions, and operators for data operations such as filtering, aggregation, time-series analysis, and more.

---

## Basic Syntax

An ES|QL query is composed of a **source command** followed by an optional series of **processing commands**, separated by a pipe character (`|`). Each command transforms the data, and the result of a query is the table produced by the final processing command.

**Example:**

```esql
FROM employees
| WHERE height > 2
| SORT last_name
```

You can write ES|QL queries as a single line or with each command on a new line for readability:

```esql
FROM employees
| WHERE height > 2
| SORT last_name
```

---

## Identifiers

- Identifiers (field or column names) must be quoted with backticks (`` ` ``) if:
  - They don’t start with a letter, `_`, or `@`
  - Any character is not a letter, number, or `_`

**Example:**

```esql
FROM index
| KEEP `1.field`
```

When referencing a function alias that itself uses a quoted identifier, escape the backticks:

```esql
FROM index
| STATS COUNT(`1.field`)
| EVAL my_count = `COUNT(``1.field``)`
```

---

## Literals

### String Literals

- Delimited by double quotes (`"`).
- If the string contains quotes, escape them (`\"`).
- Triple quotes (`"""`) can be used for convenience.

**Examples:**

```esql
FROM index
| WHERE first_name == "Georgi"

ROW name == """Indiana "Indy" Jones"""
```

Special characters:
- `\r` (carriage return)
- `\n` (line feed)
- `\t` (tab)

### Numeric Literals

- Decimal and scientific notation are supported.

**Examples:**

```esql
ROW a = 1969, b = 3.14, c = .1234, d = 4E5, e = 1.2e-3, f = -.1e2
```

---

## Comments

- Single line: `//`
- Block: `/* ... */`

**Examples:**

```esql
// Query the employees index
FROM employees
| WHERE height > 2

FROM /* Query the employees index */ employees
| WHERE height > 2

FROM employees
/* Query the
 * employees
 * index */
| WHERE height > 2
```

---

## Timespan Literals

**Timespan literals** express datetime intervals and durations. They are a combination of a number and a temporal unit (e.g., `1 day`, `24h`, `7 weeks`). Whitespace is not significant:

- `1day`
- `1 day`
- `1       day`

Timespan literals are used in many ES|QL functions and commands, such as `DATE_TRUNC`, `BUCKET`, and in date math expressions.

---

## Function Named Parameters

Some functions (like `MATCH`) support named parameters using JSON-like syntax:

```esql
FROM library
| WHERE match(author, "Frank Herbert", {"minimum_should_match": 2, "operator": "AND"})
| LIMIT 5
```

---

# Examples: Using Timespan Literals in ES|QL

Below are several ES|QL queries demonstrating the use of timespan literals with different commands and functions. Each example uses a different interval or unit, and combines ISO timestamps, `NOW()`, and timespan literals.

---

### 1. Filter Events from the Last 24 Hours

```esql
FROM logs-*
| WHERE @timestamp >= NOW() - 24h
| SORT @timestamp DESC
| LIMIT 10
```
*This query retrieves the 10 most recent log entries from the last 24 hours.*

---

### 2. Aggregate Events into 1-Hour Buckets for the Last Day

```esql
FROM logs-*
| WHERE @timestamp >= NOW() - 1 day AND @timestamp < NOW()
| STATS event_count = COUNT(*) BY hour_bucket = BUCKET(@timestamp, 1 hour)
| SORT hour_bucket
```
*This query counts events per hour for the last day, using `BUCKET` with a `1 hour` timespan.*

---

### 3. Calculate Average Value per Day for the Last Week

```esql
FROM metrics
| WHERE timestamp >= NOW() - 7 days
| STATS avg_value = AVG(value) BY day = DATE_TRUNC(1 day, timestamp)
| SORT day
```
*This query calculates the daily average of the `value` field for the past 7 days, using `DATE_TRUNC` with a `1 day` interval.*

---

### 4. Group Data into Weekly Buckets Over a Custom Range

```esql
FROM sales
| WHERE sale_date >= "2024-05-01T00:00:00Z" AND sale_date < "2024-06-01T00:00:00Z"
| STATS total_sales = SUM(amount) BY week = BUCKET(sale_date, 1 week)
| SORT week
```
*This query sums sales amounts per week for May 2024, using `BUCKET` with a `1 week` interval.*

---

### 5. Find Events in the Last 3 Hours and Truncate to 30-Minute Intervals

```esql
FROM events
| WHERE event_time >= NOW() - 3h
| EVAL interval = DATE_TRUNC(30 minutes, event_time)
| STATS count = COUNT(*) BY interval
| SORT interval
```
*This query counts events in 30-minute intervals for the last 3 hours, using `DATE_TRUNC` with a `30 minutes` timespan.*

---

### 6. Calculate Median Value in 15-Minute Buckets for the Last 2 Hours

```esql
FROM sensor_data
| WHERE reading_time >= NOW() - 2h
| STATS median_reading = MEDIAN(reading) BY bucket = BUCKET(reading_time, 15 minutes)
| SORT bucket
```
*This query calculates the median sensor reading in 15-minute buckets for the last 2 hours.*

---

### 7. Filter and Aggregate Using Weeks and Days

```esql
FROM activity_logs
| WHERE activity_date >= NOW() - 2 weeks
| STATS daily_count = COUNT(*) BY day = DATE_TRUNC(1 day, activity_date)
| SORT day
```
*This query counts activities per day for the last two weeks.*

---

## Summary

- **ES|QL** uses a piped syntax for composing queries.
- **Timespan literals** (e.g., `1 day`, `24h`, `7 weeks`) are used for date math, bucketing, and truncation.
- **Commands and functions** such as `BUCKET`, `DATE_TRUNC`, `NOW()`, and `WHERE` support timespan literals.
- **Identifiers** and **literals** follow specific quoting and escaping rules.
- **Comments** can be added using `//` or `/* ... */`.

For a complete list of commands, functions, and operators, refer to the [ES|QL Reference](#).

---
```