ObjectQL
/api/v1/data/* 、ビュー、レポート、AI ツールで使用される構造化クエリ形式。
ObjectQL
ObjectQL は、データエンジンが消費する JSON クエリ形式です。
/api/v1/data/:object が受け付けるもの、ビューがコンパイルされる先、レポートが
シリアライズされる形式、そして AI の query_data ツールが生成するものです。
2 つの形式があります:
- シンプルリスト —
where、orderBy、limit、expandなどをGET /api/v1/data/:objectのクエリ文字列パラメータとして渡します。 - アドバンスドクエリ — 完全なクエリボディを
/api/v1/data/:object/queryに POST します(groupByとaggregationsには必須)。
クエリの形式
{
object: string, // required — target object name
fields?: string[], // projection (default: all visible fields)
where?: FilterCondition, // see Filters
orderBy?: SortNode[], // [{ field, order: 'asc' | 'desc' }]
limit?: number, // page size
offset?: number, // offset pagination
cursor?: string, // cursor pagination (preferred)
expand?: string[], // batch-resolve relation fields
joins?: JoinNode[], // explicit joins (inner | left | right | full)
groupBy?: (string | GroupByNode)[],
aggregations?: AggregationNode[], // sum/avg/count/min/max/...
having?: FilterCondition, // filter after aggregation
distinct?: boolean
}スキーマのソース: packages/spec/src/data/query.zod.ts。
フィルター
where は条件のツリーです。フィールド演算子には
$ のプレフィックスが付きます。論理結合子($and、$or、$not)はトップレベルに配置されます。
比較
| 演算子 | 例 | 備考 |
|---|---|---|
$eq | { status: { $eq: "open" } } | 等価 |
$ne | { priority: { $ne: "low" } } | 不等価 |
$gt, $gte, $lt, $lte | { amount: { $gte: 1000 } } | 比較 |
すべての比較演算子は、フィールド間比較のためのフィールド参照も受け付けます:
{ end_at: { $gt: { $field: "start_at" } } }。
集合と範囲
| 演算子 | 例 |
|---|---|
$in | { status: { $in: ["new","open"] } } |
$nin | { owner_id: { $nin: ["u_1","u_2"] } } |
$between | { created_at: { $between: ["2026-01-01","2026-02-01"] } } |
文字列
| 演算子 | 例 | 備考 |
|---|---|---|
$contains | { subject: { $contains: "refund" } } | 大文字小文字を区別しない |
$notContains | { notes: { $notContains: "test" } } | |
$startsWith | { email: { $startsWith: "@" } } | |
$endsWith | { email: { $endsWith: "@acme.com" } } |
Null と存在
| 演算子 | 例 |
|---|---|
$null | { closed_at: { $null: true } } |
$exists | { external_id: { $exists: false } } |
論理結合子
{
"$and": [
{ "status": { "$eq": "open" } },
{
"$or": [
{ "priority": { "$in": ["high", "urgent"] } },
{ "due_at": { "$lt": { "$cel": "now()" } } }
]
}
]
}CEL 式は { "$cel": "..." } で埋め込むことができます。サーバーがクエリ実行時に
評価する「現在時刻基準」のフィルターに便利です。
ソート
"orderBy": [
{ "field": "priority", "order": "desc" },
{ "field": "created_at", "order": "asc" }
]クエリ文字列の短縮形: ?orderBy=-priority,created_at。
ページネーション
カーソル(推奨)。 レスポンスには nextCursor が含まれます。
それを次のリクエストの cursor として渡し戻します。
GET /api/v1/data/ticket?limit=50&orderBy=-created_at
→ { items: [...], nextCursor: "eyJ..." }
GET /api/v1/data/ticket?limit=50&cursor=eyJ...オフセット。 よりシンプルですが、大きなテーブルでは性能が低下します。
GET /api/v1/data/ticket?limit=50&offset=200ランタイムはオブジェクトごとに ObjectSpec.maxPageSize を通じて limit の上限を
設定します(デフォルト 200)。
リレーション — expand
expand は外部キーをバッチで解決するため、N+1 を回避できます。
{
"object": "support_ticket",
"expand": ["assignee", "customer.account"],
"limit": 20
}各 ticket を、ID だけではなくネストされたオブジェクトとして実体化された
assignee と customer.account とともに返します。
ジョイン
メタデータグラフ外でのアドホックなジョインの場合:
"joins": [
{ "type": "left", "object": "user", "as": "u", "on": "assignee_id = u.id" }
]type: inner | left | right | full。ジョインされたテーブルは、
as エイリアスを通じて where、orderBy、aggregations でアクセスできます。
集計
POST /api/v1/data/:object/query のみ。
{
"object": "order",
"where": { "status": { "$ne": "cancelled" } },
"groupBy": [
"customer_id",
{ "field": "created_at", "dateGranularity": "month" }
],
"aggregations": [
{ "function": "sum", "field": "amount", "alias": "total_sales" },
{ "function": "count", "alias": "order_count" }
],
"having": { "total_sales": { "$gt": 10000 } },
"orderBy": [{ "field": "total_sales", "order": "desc" }],
"limit": 25
}関数: count、sum、avg、min、max、count_distinct、
array_agg、string_agg。
日付の粒度(時間バケット化された group-by 用):
day | week | month | quarter | year。
Distinct
{ "object": "ticket", "fields": ["status"], "distinct": true }検索
searchable: true のフィールドにわたる全文検索は
GET /api/v1/search?q=...&object=ticket で公開されています。オブジェクトごとの
スコアリングルールはオブジェクト仕様で設定されます。
ObjectQL が登場する場所
GET /api/v1/data/:object— クエリ文字列形式POST /api/v1/data/:object/query— 完全なボディ、集計をサポート- ビュー定義(
filter、sort)— ObjectQL にコンパイルされる - レポート — ObjectQL にシリアライズされる
- AI の
query_dataツール — 承認キュー用の ObjectQL ボディを 生成する
関連項目
- REST API — ObjectQL を消費するエンドポイント
- Field types — クエリ可能なもの
- CEL —
$celフィルター内で使用される式言語 @objectstack/spec/data/query.zod.ts— 正式なスキーマ