Query Builder
Build ad-hoc queries across all your analytics, error, trace, and log data.
Overview#
Discover is a powerful query builder that lets you run ad-hoc queries across all data types in JustAnalytics -- events, errors, spans, and logs. Build custom tables, aggregate metrics, group by dimensions, and visualize results as charts, all without writing SQL.
Data Sources#
Discover can query four data sources:
| Source | Description | Example Fields |
|--------|-------------|----------------|
| Events | Analytics events (pageviews, clicks, custom) | url, referrer, browser, country, eventType, properties.* |
| Errors | Client and server-side errors | message, type, stack, browser, os, environment, release |
| Spans | Distributed trace spans | name, serviceName, duration, statusCode, httpMethod, dbStatement |
| Logs | Server-side log entries | message, level, serviceName, traceId, metadata.* |
Select a data source from the dropdown at the top of the Discover page.
Column Picker#
Choose which fields appear in your results table.
Adding Columns#
- Click Add Column to open the field picker
- Browse available fields organized by category (Basic, HTTP, User, Custom, etc.)
- Click a field to add it as a column
- Drag columns to reorder
- Click the X on a column header to remove it
Available Column Types#
- Raw fields -- display the field value directly (e.g.,
url,browser,message) - Aggregated fields -- compute an aggregate across rows (e.g.,
count(),avg(duration)) - Computed fields -- derived values (e.g.,
error_rate= errors / total)
Default Columns#
Each data source has sensible defaults:
- Events: timestamp, eventType, url, browser, country
- Errors: timestamp, message, type, browser, count
- Spans: timestamp, name, serviceName, duration, statusCode
- Logs: timestamp, level, serviceName, message
Filter Builder#
Narrow your results with powerful filter conditions.
Simple Filters#
Click Add Filter and configure:
- Field -- the field to filter on
- Operator -- comparison type
- Value -- the value to compare against
Supported Operators#
| Operator | Description | Example |
|----------|-------------|---------|
| is | Exact match | browser is Chrome |
| is not | Exclude exact match | country is not US |
| contains | Substring match | url contains /api |
| does not contain | Exclude substring | message does not contain timeout |
| starts with | Prefix match | url starts with /dashboard |
| ends with | Suffix match | url ends with .json |
| greater than | Numeric comparison | duration greater than 1000 |
| less than | Numeric comparison | statusCode less than 400 |
| in | Match any in list | level in [error, fatal] |
| not in | Exclude list | serviceName not in [healthcheck] |
| exists | Field is present | traceId exists |
| does not exist | Field is absent | userId does not exist |
AND/OR Groups#
Build complex filter logic with nested groups:
WHERE
(browser is "Chrome" OR browser is "Firefox")
AND country is "US"
AND duration greater than 500
Click the AND/OR toggle between filter groups to switch logic. Nest groups by clicking Add Group inside an existing group.
Aggregations#
Transform raw data into summary statistics.
Available Aggregations#
| Function | Description | Applicable To |
|----------|-------------|---------------|
| count() | Number of matching rows | All data sources |
| count_unique(field) | Distinct count of field values | All fields |
| avg(field) | Average of numeric field | duration, value, custom metrics |
| sum(field) | Sum of numeric field | duration, value, amount |
| min(field) | Minimum value | Numeric fields |
| max(field) | Maximum value | Numeric fields |
| p50(field) | 50th percentile (median) | duration, numeric fields |
| p75(field) | 75th percentile | duration, numeric fields |
| p95(field) | 95th percentile | duration, numeric fields |
Adding Aggregations#
- Click Add Column
- Select the aggregation function from the dropdown
- If the function takes a field argument (e.g.,
avg), select the field - The column appears with the aggregation label (e.g., "avg(duration)")
Multiple Aggregations#
Combine multiple aggregations in a single query:
Columns: serviceName, count(), avg(duration), p95(duration), count_unique(traceId)
Group By: serviceName
Group By#
Aggregate results by one or more dimensions.
Adding Group By#
- Click Group By and select a field
- Results are grouped by unique values of that field
- Add multiple group-by fields for nested grouping
Examples#
Errors by browser:
Data Source: Errors
Columns: browser, count(), count_unique(message)
Group By: browser
Order By: count() DESC
Latency by endpoint:
Data Source: Spans
Columns: name, avg(duration), p95(duration), count()
Group By: name
Filter: kind is "server"
Order By: p95(duration) DESC
Pageviews by country and device:
Data Source: Events
Columns: country, deviceType, count()
Group By: country, deviceType
Order By: count() DESC
Order By#
Sort results by any column:
- Click a column header to sort ascending
- Click again to sort descending
- Or use the Order By control to select a column and direction
When using aggregations, you can order by any aggregated column (e.g., sort by p95(duration) descending to find slowest endpoints).
Results Display#
Table View#
The default view shows results as a sortable, paginated table. Each row is clickable to see the full detail (event detail, error detail, span waterfall, or log entry).
- Pagination: 25, 50, or 100 rows per page
- Export: download results as CSV or JSON
Chart View#
Toggle to chart view to visualize aggregated results:
| Chart Type | Best For | |------------|----------| | Bar | Comparing categories (errors by browser, latency by service) | | Line | Trends over time (error count per hour, p95 per day) | | Area | Stacked trends (pageviews by country over time) | | Pie | Proportions (traffic by device type) | | Heatmap | Two-dimensional comparison (hour of day vs day of week) |
Time Series Mode#
When you add a time-based group by (e.g., "Group By: timestamp (1 hour)"), results automatically switch to a time-series chart showing the aggregation over time.
Saving Queries#
Save frequently-used queries for quick access:
- Build your query (data source, columns, filters, aggregations)
- Click Save Query
- Enter a name and optional description
- The query appears in Saved Queries in the Discover sidebar
Saved queries preserve:
- Data source selection
- Column configuration
- Filters and filter groups
- Aggregations and group-by
- Sort order
- Chart type and visualization settings
Sharing Saved Queries#
Saved queries are scoped to the site. All users with access to the site can see and use saved queries. To share a query externally, use the Copy Link button to generate a URL with the query encoded in parameters.
Drag-and-Drop Exploration#
Discover supports an intuitive drag-and-drop mode for quick exploration:
- Toggle Exploration Mode at the top of the page
- Available fields appear in a left sidebar panel
- Drag fields to the Columns area to add them to the table
- Drag fields to the Filters area to filter by them
- Drag numeric fields to the Aggregations area to compute statistics
- Drag fields to the Group By area to group results
This mode is ideal for ad-hoc investigation when you are not sure what you are looking for.
Common Query Examples#
Top Error Messages (Last 24h)#
Data Source: Errors
Columns: message, count(), count_unique(browser)
Group By: message
Time Range: Last 24 hours
Order By: count() DESC
Limit: 20
Slowest API Endpoints#
Data Source: Spans
Columns: name, avg(duration), p50(duration), p95(duration), count()
Group By: name
Filter: kind is "server" AND duration greater than 100
Order By: p95(duration) DESC
Pageviews by Country (This Week)#
Data Source: Events
Columns: country, count(), count_unique(visitorHash)
Group By: country
Filter: eventType is "pageview"
Time Range: This week
Order By: count() DESC
Error Rate by Release#
Data Source: Errors
Columns: release, count()
Group By: release
Time Range: Last 7 days
Order By: count() DESC
Chart: Bar
Log Volume by Level#
Data Source: Logs
Columns: level, count()
Group By: level, timestamp (1 hour)
Time Range: Last 24 hours
Chart: Stacked Area