mcpField
D
dataset-query

dataset-query

github.com/stahuraデータ・データベース24197 回インストール26 週間前に更新
リポジトリ

dataset-query について

Domo アプリ開発者向けの JavaScript クエリビルダーです。チェーン可能な API でフィルター、集計、日付操作を組み立てられ、埋め込みダッシュボードのページフィルターも反映します。

主な機能

  1. 01チェーン形式のデータセットクエリ
  2. 02列選択と条件フィルター
  3. 03グループ化、集計、並べ替え
  4. 04日付粒度と期間のクエリ
  5. 05行数制限とオフセット設定

活用シーン

  1. 01ダッシュボードのページフィルターを使ったデータ取得
  2. 02必要な列と集計値だけの取得
  3. 03日付期間ごとの指標集計

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/stahura/domo-ai-vibe-rules --skill dataset-query

インストール後、Claude Code で/dataset-queryを入力して読み込まれたか確認します。

詳細

@domoinc/query - データクエリビルダー

重要: Domo アプリ内のすべてのデータセットクエリには、Query API(@domoinc/query 経由)を使用してください。これは次の理由から不可欠です。

  1. ページフィルターとの連携 - アプリが Domo ダッシュボードに埋め込まれている場合、Query API はページレベルのフィルターを自動的に適用します。ダッシュボードのフィルター変更に応じて動作する必要があるアプリでは、特に重要です。

  2. パフォーマンス - Query API を使用すると、データセット全体を取得するのではなく、必要な集計レベルで必要なデータだけをクエリできます。大規模なデータセットでは特に、パフォーマンス上不可欠です。

  3. サーバーサイド処理 - 集計とフィルタリングは Domo のサーバー上で行われるため、データ転送量とクライアントサイドでの処理を削減できます。

Query 以外のデータアクセス: アプリが @domoinc/query を使用せずにデータへアクセスする場合(Code Engine の呼び出し、SqlClient による生 SQL、クエリパラメーターなしの /data/v1/ への直接アクセスなど)、ページフィルターは自動適用されません。domo.onFiltersUpdated(domo-js を参照)を登録し、フィルター値をパラメーターとしてデータソースに手動で渡す必要があります。App Studio の変数にも同じことが当てはまります。domo.onVariablesUpdated を使用して変数の変更を受け取り、クエリに反映してください。

Query ライブラリは、複雑なデータクエリを構築するためのチェーン可能な API を提供します。domo.get() および /data/v1/ エンドポイントで使用できる URL を生成します。

npm/yarn:

yarn add @domoinc/query
import Query from '@domoinc/query';

CDN(Vanilla JavaScript):

<script src="https://cdn.jsdelivr.net/npm/@domoinc/[email protected]/dist/main.min.js"></script>
// Query is available globally after CDN script loads
const data = await new Query()
  .select(['region', 'sales'])
  .fetch('sales-dataset');

基本的な使い方

// Simple query
const data = await new Query()
  .select(['region', 'sales', 'date'])
  .fetch('sales-dataset');

// With filtering
const filtered = await new Query()
  .select(['region', 'product', 'sales'])
  .where('sales').greaterThan(1000)
  .where('region').in(['North', 'South'])
  .fetch('sales-dataset');

// With grouping and aggregation
const summary = await new Query()
  .select(['region', 'sales', 'quantity'])
  .groupBy('region')
  .groupBy({ sales: 'sum', quantity: 'avg' })
  .orderBy('sales', 'descending')
  .limit(10)
  .fetch('sales-dataset');

Select

// Select specific columns
new Query().select(['col1', 'col2', 'col3'])

// Select all (omit select)
new Query().fetch('dataset')

Where フィルター

すべてのフィルターメソッドは、チェーンでつなげられるよう Query を返します。

// Comparison filters
.where('amount').lessThan(100)           // .lt(100)
.where('amount').lessThanOrEqual(100)    // .lte(100)
.where('amount').greaterThan(100)        // .gt(100)
.where('amount').greaterThanOrEqual(100) // .gte(100)
.where('amount').equals(100)
.where('amount').notEquals(100)
.where('amount').between(100, 500)

// String filters
.where('name').contains('test')
.where('name').notContains('test')

// List filters
.where('category').in(['A', 'B', 'C'])
.where('status').notIn(['deleted', 'archived'])

// Multiple conditions (AND)
.where('amount').greaterThan(100)
.where('status').equals('active')
.where('region').in(['North', 'South'])

Group By

// Group by single column
.groupBy('region')

// Group by multiple columns
.groupBy('region')
.groupBy('product')

// Group by column with aggregations (second parameter)
.groupBy('region', { 
  sales: 'sum',
  quantity: 'avg',
  price: 'max',
  orders: 'count',
  skus: 'unique'
})

// Multiple groupBy calls
.groupBy('region')
.groupBy('product', { sales: 'sum', orders: 'count' })

集計関数:

  • 'count' - 行数をカウント
  • 'sum' - 値を合計
  • 'avg' - 値の平均
  • 'min' - 最小値
  • 'max' - 最大値
  • 'unique' - 重複を除いた値の数をカウント
重要 - 集計キーの構文

集計キーには、カスタムエイリアスではなく、データセットの実際のフィールド名を使用する必要があります。

集計オブジェクトのキーによって、出力プロパティ名が決まります。フィールド名と一致しないエイリアスを使用すると、[object Object] エラーが発生します。

// ✅ CORRECT - Keys match actual field names
// If your dataset has fields: 'Sales_Amount', 'Order_Qty'
.groupBy('region', { 
  Sales_Amount: 'sum',   // Key matches dataset field
  Order_Qty: 'count'     // Key matches dataset field
})

// Results: [{ region: 'North', Sales_Amount: 50000, Order_Qty: 150 }]

// ❌ WRONG - Custom aliases as keys cause [object Object] errors
.groupBy('region', { 
  totalSales: 'sum',     // 'totalSales' is not a field name!
  orderCount: 'count'    // 'orderCount' is not a field name!
})

// ✅ If you need custom names, rename AFTER fetching:
const data = await new Query()
  .groupBy('region', { Sales_Amount: 'sum' })
  .fetch('sales');

const renamed = data.map(row => ({
  region: row.region,
  totalSales: row.Sales_Amount  // Rename here
}));

Order By

.orderBy('sales', 'descending')  // or 'desc'
.orderBy('date', 'ascending')    // or 'asc'

// Multiple sort columns
.orderBy('region', 'ascending')
.orderBy('sales', 'descending')

Limit と Offset

.limit(100)    // Max rows
.offset(50)     // Skip rows (for pagination)

// Pagination example
const page = 2;
const pageSize = 25;
new Query()
  .limit(pageSize)
  .offset((page - 1) * pageSize)
  .fetch('dataset');

日付操作

dateGrain - 日付期間でグループ化
// Group by month
.dateGrain('order_date', 'month')

// Group by month with aggregations
// NOTE: Aggregation keys must be actual field names!
.dateGrain('order_date', 'month', { Revenue: 'sum', Order_Count: 'count' })

// Available grains: 'day', 'week', 'month', 'quarter', 'year'
.dateGrain('date', 'day')
.dateGrain('date', 'week')
.dateGrain('date', 'month')
.dateGrain('date', 'quarter')
.dateGrain('date', 'year')

重要: 3 番目のパラメーター(集計)は groupBy と同じルールに従います。キーには、データセットの実際のフィールド名を指定してください。

// ✅ CORRECT - field names as keys
.dateGrain('order_date', 'month', { Sales_Amount: 'sum' })

// ❌ WRONG - custom aliases cause errors
.dateGrain('order_date', 'month', { totalSales: 'sum' })
periodToDate - YTD、MTD、QTD など
// Year to date
.periodToDate('date', 'year')

// Month to date
.periodToDate('date', 'month')

// Quarter to date
.periodToDate('date', 'quarter')

// Full example
const ytdSales = await new Query()
  .select(['date', 'sales'])
  .periodToDate('date', 'year')
  .groupBy({ sales: 'sum' })
  .fetch('sales');
previousPeriod - 前期間との比較
// Last year
.previousPeriod('date', 'year')

// Last month
.previousPeriod('date', 'month')

// Last quarter
.previousPeriod('date', 'quarter')
rollingPeriod - ローリング期間
// Last 30 days
.rollingPeriod('date', 'days', 30)

// Last 12 weeks
.rollingPeriod('date', 'weeks', 12)

// Last 6 months
.rollingPeriod('date', 'months', 6)

// Last 4 quarters
.rollingPeriod('date', 'quarters', 4)

// Last 3 years
.rollingPeriod('date', 'years', 3)

追加オプション

// Use fiscal calendar
.useFiscalCalendar(true)

// Enable beast modes (calculated fields)
.useBeastModes()

// ⚠️ WARNING: .aggregate() does NOT work in practice
// It causes error: "DA0057: An alias list was provided but it could not be parsed"
// Use .groupBy() with a grouping column instead, or .select() + client-side aggregation
// ❌ .aggregate({ total: 'sum', average: 'avg' })  // DOES NOT WORK

完全な例

// Sales dashboard query
const salesByRegion = await new Query()
  .select(['region', 'product_category', 'sales', 'quantity', 'date'])
  .where('sales').greaterThan(0)
  .where('date').greaterThanOrEqual('2024-01-01')
  .dateGrain('date', 'month')
  .groupBy('region')
  .groupBy('product_category')
  .groupBy({ sales: 'sum', quantity: 'sum', orders: 'count' })
  .orderBy('sales', 'descending')
  .limit(100)
  .fetch('sales-dataset');

// YoY comparison
const thisYear = await new Query()
  .select(['month', 'revenue'])
  .periodToDate('date', 'year')
  .dateGrain('date', 'month', { revenue: 'sum' })
  .fetch('revenue');

const lastYear = await new Query()
  .select(['month', 'revenue'])
  .previousPeriod('date', 'year')
  .dateGrain('date', 'month', { revenue: 'sum' })
  .fetch('revenue');

// Trend analysis - last 90 days
const trend = await new Query()
  .select(['date', 'sales', 'orders'])
  .rollingPeriod('date', 'days', 90)
  .dateGrain('date', 'day', { sales: 'sum', orders: 'count' })
  .orderBy('date', 'ascending')
  .fetch('sales');

コメント