# groundcover Query Language

### What is the groundcover Query Language?

The groundcover Query Language is inspired by LogsQL but designed specifically for groundcover's observability platform. It uses a pipeline-based syntax where operations flow from left to right using the pipe operator `|`.

You can use it to:

* [**Filter**](https://docs.groundcover.com/use-groundcover/querying-your-groundcover-data/groundcover-query-language/filters) logs, traces, and events with flexible search patterns
* [**Aggregate**](https://docs.groundcover.com/use-groundcover/querying-your-groundcover-data/groundcover-query-language/aggregations) data with statistical functions (count, avg, percentiles, etc.)
* [**Join**](https://docs.groundcover.com/use-groundcover/querying-your-groundcover-data/groundcover-query-language/join-operations) multiple queries
* [**Transform**](https://docs.groundcover.com/use-groundcover/querying-your-groundcover-data/groundcover-query-language/pipeline-operations) results with sorting, limiting, field selection, and more

### Where Can You Use It?

The query language is available in:

1. [**Data Explorer**](https://docs.groundcover.com/use-groundcover/querying-your-groundcover-data/explore-and-monitors-query-builder) - Query and visualize data interactively
2. [**Monitors**](https://docs.groundcover.com/use-groundcover/monitors) - Create alerts based on query results
3. [**Dashboards**](https://docs.groundcover.com/use-groundcover/dashboards-and-alerts) - Build custom visualizations
4. [**APIs**](https://docs.groundcover.com/use-groundcover/remote-access-and-apis/api-examples/query-logs/the-basics-of-querying-logs) - Query data programmatically

#### Code Mode

Access the query language through **Code Mode** in the Data Explorer and Monitors query builder. Code Mode gives you full control over your queries with syntax highlighting and auto-completion.

### Basic Query Structure

All queries follow this general pattern:

```
<filters> | <operation1> | <operation2> | ...
```

**Example - Simple filter:**

```
level:error
```

*Find all error logs*

**Example - Filter with aggregation:**

```
level:error | stats by (workload) count()
```

*Count errors per workload*

**Example - Full pipeline:**

```
level:error namespace:production | stats by (workload) count() as errors | sort by (errors desc) | limit 10
```

*Top 10 workloads with errors in production*

### Core Components

#### Filters

Filters narrow down your data using field-value matching.

```
level:error
```

```
workload:auth-service status_code:>=500
```

```
"*timeout*" namespace:prod
```

#### Aggregations

Compute metrics from filtered data using `stats`.

```
* | stats count()
```

```
* | stats by (workload) avg(duration_seconds)
```

#### Join Operations

Combine data from multiple queries.

```
* | stats by (user_id) count() | join by (user_id) (event:purchase | stats by (user_id) count())
```

#### Pipeline Operations

Transform results with sort, limit, fields, and more.

```
* | sort by (timestamp desc)
```

```
* | stats by (endpoint) count() | sort by (count desc) | limit 10
```

```
* | fields timestamp, level, message, workload
```

### Differences from Other Query Languages

#### vs. LogsQL

* **Case-insensitive** by default (LogsQL is case-sensitive)
* **Implicit OR** for same-field filters: `level:error level:warn` = `level:error OR level:warn`
* **Time bucketing** configured externally, not in `stats by (_time:5m)`
* **Both** `*value*` and `~"value"` syntax for substring matching

#### vs. SQL

* **Pipeline-based** - Left-to-right flow with `|` vs. declarative SELECT/FROM/WHERE
* **No tables** - Query logs/traces/events directly
* **Implicit AND** - Multiple filters are ANDed automatically
* **Function syntax** - `stats by (field) count()` vs. `SELECT field, COUNT(*) GROUP BY field`
