메인 콘텐츠로 건너뛰기

Documentation Index

Fetch the complete documentation index at: https://docs.chainstream.io/llms.txt

Use this file to discover all available pages before exploring further.

메트릭이란?

메트릭은 Cube Record 타입의 필드로 제공되는 집계 함수입니다. GraphQL 쿼리 안에서 직접 통계를 계산해 후처리 없이 쓸 수 있습니다. 차원 필드와 함께 메트릭 필드를 선택하면, 선택한 차원으로 그룹화한 뒤 각 그룹에 대해 메트릭을 계산합니다. 지원 메트릭:
메트릭SQL에 대응설명
countCOUNT(*) 또는 COUNT(column)행 수 또는 고유 값 수
sumSUM(column)숫자 합계
avgAVG(column)숫자 평균
minMIN(column)최솟값
maxMAX(column)최댓값
uniqCOUNT(DISTINCT column)고유 값 개수

Record 타입의 메트릭 필드

메트릭은 각 Cube의 Record 타입 최상위 필드로 나타납니다. 모든 Cube가 모든 메트릭을 지원하는 것은 아니며, Cube 정의에 따릅니다.
type DEXTradesRecord {
  # Dimension fields...
  Block { ... }
  Trade { ... }

  # Metric fields
  count: Int
  sum(of: DEXTradesSumOf!): Float
}
메트릭을 쓰려면 필드 선택에 포함하면 됩니다:
query {
  Solana {
    DEXTrades(
      tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
      where: { Block: { Time: { after: "2025-03-27T00:00:00Z" } } }
    ) {
      count
      Trade { Dex { ProtocolName } }
    }
  }
}
이 쿼리는 DEX 거래를 프로토콜 이름별로 그룹화하고 각 그룹의 건수를 반환합니다.

of 파라미터

sum, avg, min, max, uniq 같은 메트릭은 어떤 차원을 집계할지 지정하는 of 파라미터가 필요합니다. of 값은 차원 경로 명명 규칙에 따라 Cube마다 생성되는 enum입니다.
sum(of: Trade_Buy_Amount)
avg(of: Trade_Buy_PriceInUSD)
min(of: Block_Time)
max(of: Trade_Sell_Amount)
uniq(of: Trade_Buy_Account_Owner)

예: DEX별 총 매수 볼륨

query {
  Solana {
    DEXTrades(
      tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
      where: { Block: { Time: { after: "2025-03-27T00:00:00Z" } } }
    ) {
      count
      sum(of: Trade_Buy_Amount)
      Trade { Dex { ProtocolName } }
    }
  }
}
응답:
{
  "data": {
    "Solana": {
      "DEXTrades": [
        {
          "count": 1842,
          "sum": 2847291.45,
          "Trade": { "Dex": { "ProtocolName": "Raydium" } }
        },
        {
          "count": 923,
          "sum": 1293847.12,
          "Trade": { "Dex": { "ProtocolName": "Orca" } }
        }
      ]
    }
  }
}

count — 행 세기

of 없이 쓰는 count 는 각 그룹의 총 행 수를 셉니다(COUNT(*) 와 동일):
query {
  Solana {
    DEXTrades(
      where: { Block: { Time: { after: "2025-03-27T00:00:00Z" } } }
    ) {
      count
    }
  }
}
차원 필드와 함께 쓰면 그룹별 건수를 반환합니다:
query {
  Solana {
    DEXTrades(
      where: { Block: { Time: { after: "2025-03-27T00:00:00Z" } } }
    ) {
      count
      Trade { Dex { ProtocolName } }
    }
  }
}

uniq — 고유 개수

uniq 는 SQL의 COUNT(DISTINCT column) 에 대응합니다. 차원의 고유 값 개수를 셀 때 사용합니다:
query {
  Solana {
    DEXTrades(
      tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
      where: { Block: { Time: { after: "2025-03-27T00:00:00Z" } } }
    ) {
      uniq(of: Trade_Buy_Account_Owner)
    }
  }
}
오늘 Solana에서 USDC를 거래한 고유 매수 지갑 수를 반환합니다.

selectWhere — HAVING 스타일 필터

selectWhere 는 SQL의 HAVING 과 비슷하게 집계 결과에 대해 필터합니다. 그룹화·집계 이후에 적용되며, 메트릭 값으로 그룹을 걸러 냅니다.
query {
  Solana {
    DEXTrades(
      where: { Block: { Time: { after: "2026-04-01T00:00:00Z" } } }
    ) {
      count(selectWhere: { gt: "100" })
      Trade { Dex { ProtocolName } }
    }
  }
}
거래가 100건을 넘은 DEX 프로토콜만 반환하고, 그보다 적은 프로토콜은 결과에서 제외됩니다.
selectWhere 값은 반드시 문자열로 넘깁니다(예: "100" 이며 100 이 아님). 내부적으로 숫자로 파싱됩니다.
selectWhere 가 지원하는 비교 연산자:
연산자설명
gt보다 큼
ge이상
lt보다 작음
le이하
eq같음
알려진 제한: selectWhere 를 쓸 때 orderBy 는 암시적 GROUP BY 에 포함된 차원(선택 중인 필드)이나 집계 결과를 참조해야 합니다. GROUP BY 에 없는 필드(예: Block_Time)로 정렬하면 DB 오류가 납니다.

실전 예: 상위 트레이더

오늘 특정 토큰에 대해 거래 건수 기준 상위 10지갑을 찾고, 총 매수 볼륨과 고유 거래 수를 표시:
query TopTraders {
  Solana {
    DEXTrades(
      tokenAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"
      where: {
        Block: { Time: { after: "2025-03-27T00:00:00Z" } }
      }
      orderBy: {descending: Block_Time}
      limit: { count: 10 }
    ) {
      count
      sum(of: Trade_Buy_Amount)
      Trade {
        Buy {
          Account { Owner }
        }
      }
    }
  }
}
응답:
{
  "data": {
    "Solana": {
      "DEXTrades": [
        {
          "count": 47,
          "sum": 892341023.5,
          "Trade": {
            "Buy": {
              "Account": { "Owner": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" }
            }
          }
        },
        {
          "count": 31,
          "sum": 451203847.2,
          "Trade": {
            "Buy": {
              "Account": { "Owner": "3kMq5RezM9XBbBGRNxP9vXkJHAfG8S7gn5WfBsHFQr7T" }
            }
          }
        }
      ]
    }
  }
}

여러 메트릭 조합

한 쿼리에서 여러 메트릭 필드를 함께 선택할 수 있습니다:
query {
  Solana {
    DEXTrades(
      tokenAddress: "So11111111111111111111111111111111111111112"
      where: {
        Block: { Time: { after: "2025-03-27T00:00:00Z" } }
      }
    ) {
      count
      sum(of: Trade_Buy_Amount)
      min(of: Trade_Buy_PriceInUSD)
      max(of: Trade_Buy_PriceInUSD)
      uniq(of: Trade_Buy_Account_Owner)
      Trade { Dex { ProtocolName } }
    }
  }
}
DEX별로 거래 건수, 총 볼륨, 가격 범위, 고유 트레이더 수를 한 번에 반환합니다.

메트릭 vs 사전 집계 Cube

자주 묻는 질문: DWD Cube에 메트릭을 쓸까, DWM/DWS Cube를 직접 조회할까?
접근언제 쓰나성능
DWD Cube의 메트릭(예: DEXTrades.count)맞춤 집계, 임시 그룹화, 유연한 시간 창느림 — 쿼리 시점에 원시 이벤트 집계
DWM Cube(예: Pairs, Tokens)표준 시계열, OHLC 차트, 시간별 볼륨빠름 — 분 단위 사전 롤업 읽기
DWS Cube(예: TokenHolders, WalletTokenPnL)현재 스냅샷, 누적 합계, 리더보드가장 빠름 — 사전 집계 요약 데이터
경험칙: 유스케이스가 DWM/DWS로 커버되면 그쪽을 쓰세요 — 사전 집계라 훨씬 빠릅니다. 사전 빌드 Cube가 지원하지 않는 맞춤 그룹화·집계가 필요할 때만 DWD + 메트릭으로 돌아가세요.

선택 가이드

Pairs(DWM)를 쓰세요. 분당 시가/고가/저가/종가/볼륨이 이미 계산되어 있습니다. DEXTrades를 직접 집계할 필요가 없습니다.
Tokens(DWM)를 쓰세요. 분당 거래 건수, 볼륨, 고유 트레이더를 미리 집계합니다.
TokenHolders(DWS)를 쓰세요. 홀더별 최신 잔액이 미리 계산되어 BalanceUpdates를 집계하는 것보다 훨씬 빠릅니다.
Trade.Dex.ProtocolName 으로 그룹화한 DEXTradescount + sum(of: Trade_Buy_Amount) 를 쓰세요. 사전 빌드 Cube에 없는 형태이므로 DWD 메트릭이 맞습니다.
WalletTokenPnL(DWS)를 쓰세요. 지갑–토큰 페어당 매수/매도 볼륨과 거래 건수가 미리 계산되어 있습니다.

다음 단계

데이터 Cube

25개 Cube와 필드 구조를 살펴봅니다.

쿼리 예시

메트릭과 집계를 쓰는 실전 쿼리 예시를 확인합니다.