ObjectOS
リファレンス

ObjectQL

/api/v1/data/* 、ビュー、レポート、AI ツールで使用される構造化クエリ形式。

ObjectQL

ObjectQL は、データエンジンが消費する JSON クエリ形式です。 /api/v1/data/:object が受け付けるもの、ビューがコンパイルされる先、レポートが シリアライズされる形式、そして AI の query_data ツールが生成するものです。

2 つの形式があります:

  • シンプルリストwhereorderBylimitexpand などを GET /api/v1/data/:object のクエリ文字列パラメータとして渡します。
  • アドバンスドクエリ — 完全なクエリボディを /api/v1/data/:object/query に POST します(groupByaggregations には必須)。

クエリの形式

{
  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 だけではなくネストされたオブジェクトとして実体化された assigneecustomer.account とともに返します。

ジョイン

メタデータグラフ外でのアドホックなジョインの場合:

"joins": [
  { "type": "left", "object": "user", "as": "u", "on": "assignee_id = u.id" }
]

type: inner | left | right | full。ジョインされたテーブルは、 as エイリアスを通じて whereorderByaggregations でアクセスできます。

集計

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
}

関数: countsumavgminmaxcount_distinctarray_aggstring_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 — 完全なボディ、集計をサポート
  • ビュー定義(filtersort)— ObjectQL にコンパイルされる
  • レポート — ObjectQL にシリアライズされる
  • AI の query_data ツール — 承認キュー用の ObjectQL ボディを 生成する

関連項目

On this page