Skip to main content
DQL (Docent Query Language) lets you query agent runs, metadata, and evaluation results using a SQL-like syntax.
For the conceptual overview of DQL, see Structured queries (DQL). For the column schema of each table, see DQL schema reference.

Execute a Query

Parameters

collection_id
str
required
ID of the collection to query.
dql
str
required
The DQL query string.
reading_plan_id
str | None
default:"None"
Optional reading plan ID for $alias substitution in queries that reference reading step aliases.
source
Literal["endpoint", "mcp"]
default:"\"endpoint\""
Analytics source for the execution path. Defaults to "endpoint"; the MCP server sets "mcp" automatically. You typically do not need to set this.
ensure_latest_results
bool
default:"False"
When True, the server refuses the optimized parquet path unless the parquet replica reflects every committed mutation, and runs the query against Postgres otherwise. Use this when you cannot tolerate parquet lag — for example, immediately after adding or deleting agent runs, or when verifying a write.

Returns

result
dict
Query result.

Errors

  • ValueErrordql is empty
  • HTTPError — Invalid DQL syntax or collection not found

Convert Results to Dicts

Parameters

dql_result
dict
required
A result dict returned by execute_dql.

Returns

rows
list[dict]
List of dictionaries, one per row, with column names as keys.

Common Query Patterns

Filter by metadata

Join with evaluation results

Count and aggregate


Allowed syntax

DQL supported keywords: Unsupported constructs include wildcard * in SELECT clauses (e.g., SELECT *, COUNT(*)), user-defined functions, and any DDL or DML commands.

SQL patterns

Bare DQL snippets for common tasks.

Filter by metadata field

Filter by date range

Count by category

Check if a metadata field exists

Numeric comparison on a JSON field

Cast JSON for aggregation

Counting transcript messages

transcripts.messages is stored as bytea (UTF-8 JSON), not jsonb. Operators like messages -> 0 or jsonb_array_length(messages) raise operator does not exist: bytea -> integer. Decode to jsonb first, then count array elements:
The same applies to transcripts.metadata_json — decode with convert_from(metadata_json, 'UTF8')::jsonb before using JSON operators. Agent runs with at least N messages in any transcript:
Per-transcript message counts (compute once in a subquery, then filter):
Reading nested transcripts.metadata_json fields:
Express filters like “≥10 messages” with the pattern above. Don’t materialize matching IDs elsewhere and paste them into a giant WHERE id IN ('…', '…', …) clause — that blows past query size limits and is hard to maintain.

Join transcripts with agent runs

Transcript counts per group

Transcript coverage audit

Finds transcript groups that are marked as must_have but have no associated transcripts.

Flagged judge results


Common gotchas

”column X does not exist”

  • DQL requires explicit column selection. Wildcards (*) are not supported.
  • Check the schema using client.get_dql_schema(collection_id) to see available columns.

Numeric comparisons not working as expected

JSON fields are strings by default. Cast them for numeric operations:

Query returns no results but data exists

  • Check that you’re querying the correct collection
  • Verify metadata field names are exact matches (case-sensitive)
  • Use ? operator to check if a field exists before filtering on it

Results truncated unexpectedly

DQL caps results at 10,000 rows. Use LIMIT and OFFSET for pagination:

“syntax error” on valid-looking SQL

Some SQL features aren’t supported in DQL:
  • No * wildcard in SELECT
  • No INSERT, UPDATE, DELETE
  • No user-defined functions