원클릭으로
drasi-queries
Guide for writing Drasi continuous queries using Cypher. Use this when asked to create, modify, or troubleshoot Drasi queries.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guide for writing Drasi continuous queries using Cypher. Use this when asked to create, modify, or troubleshoot Drasi queries.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | drasi-queries |
| description | Guide for writing Drasi continuous queries using Cypher. Use this when asked to create, modify, or troubleshoot Drasi queries. |
Use this skill when developing Drasi ContinuousQuery definitions with Cypher. If the user is not working with Drasi, do not apply this skill.
IMPORTANT: Use the context7 MCP server with library ID /drasi-project/docs to get the latest Drasi documentation and Cypher syntax. Do not assume—verify current supported features.
Verify-first any Drasi capability or function behavior that may be version-dependent:
[VERIFY]
EvidenceType = Docs | ReleaseNotes | Issue | Repro
WhereToCheck = <URL, repo, command, or repro steps>
drasi version output and keep this line current; version not verified in this repo).queryLanguage: GQL.collect, DISTINCT, ORDER BY, LIMIT) should be treated as unsupported unless release notes state otherwise.| Task type | Function | Notes / When to use |
|---|---|---|
| Detect state transition | drasi.previousDistinctValue() | Ignores repeated identical values. |
| Compare last-known values | drasi.previousValue() | Detect any change between revisions. |
| Evaluate sustained truth | drasi.trueFor() | Requires continuous "true" state for duration. |
| Evaluate timed condition | drasi.trueLater() | Pending result until specified timestamp. |
| Retrieve version snapshot | drasi.getVersionByTimestamp() | Requires temporal index. |
| Compute trend | drasi.linearGradient() | Aggregate slope detection (telemetry, rate rise). |
| Change timestamps | drasi.changeDateTime() | Windowing and recency checks against element's last change time. Evidence: Drasi custom functions docs (link below). |
| Historical lookup (range) | drasi.getVersionsByTimeRange() | Requires temporal index. Evidence: Drasi custom functions docs (link below). |
Evidence: Drasi custom functions docs (https://github.com/drasi-project/docs/blob/main/docs/content/reference/query-language/drasi-custom-functions.md).
trueFor, historical versions), and when you need query results that reflect graph state transitions.MATCH (a), (b)) unless absolutely required; they scale poorly.WHERE before aggregations to reduce per-diff work.| Feature | Example |
|---|---|
MATCH, WHERE, RETURN | MATCH (n:Node) WHERE n.id > 5 RETURN n |
WITH ... count() | WITH n.category AS cat, count(*) AS cnt |
| Aggregations | max(), min(), sum(), avg(), count() |
coalesce() | RETURN coalesce(n.value, 0) |
drasi.changeDateTime() | WHERE drasi.changeDateTime() > datetime() |
drasi.previousValue() | WHERE i.amount > drasi.previousValue(i.amount) |
drasi.previousDistinctValue() | WHERE drasi.previousDistinctValue(c.status) = 'pending' |
| Graph relationships | MATCH (a)-[:LIKES]->(b) |
| Identifier escaping | Use backticks for special chars: MATCH (n:`Special-Label`) |
| Feature | Status | Workaround |
|---|---|---|
collect() | ⚠️ Not in supported subset | Use WITH ... count() pattern |
DISTINCT | ❌ Not in supported subset | Use WITH ... count() for grouping |
ORDER BY | ❌ Not in supported subset | Sort client-side |
LIMIT | ❌ Not in supported subset | Filter client-side |
Source: Drasi Cypher support docs (https://github.com/drasi-project/docs/blob/main/docs/content/reference/query-language/cypher.md)
MATCH (w:WishlistItem)
WITH w.text AS item, count(*) AS frequency
WHERE frequency > 0
RETURN item, frequency
MATCH (w1:WishlistItem), (w2:WishlistItem)
WHERE w1.toyName = w2.toyName
AND w1.childId <> w2.childId
RETURN w1.childId AS child1,
w2.childId AS child2,
w1.toyName AS duplicate
MATCH (w:WishlistItem)
WHERE drasi.changeDateTime() > datetime() - duration('PT24H')
WITH w.toyName AS toy, count(*) AS requests
WHERE requests >= 5
RETURN toy, requests
Queries must use the middleware label, NOT the event hub name:
# In Source definition
middleware:
- kind: map
my-event-hub:
insert:
- label: WishlistItem # <-- Use THIS in queries
# Map event types to labels (event type != hub/topic name)
middleware:
- kind: map
toy-events-hub:
insert:
- label: WishlistItem
when:
eventType: wishlist.item.created
- label: ChildProfile
when:
eventType: child.profile.updated
# ✅ CORRECT
MATCH (w:WishlistItem)
# ❌ WRONG
MATCH (w:`my-event-hub`)
Always use Drasi CLI, NOT kubectl. Deploy in this order and verify each step:
drasi apply -f queries.yaml -n drasi-system
drasi describe query my-query -n drasi-system
New Feature: Drasi now supports Graph Query Language (GQL) in addition to Cypher!
kind: ContinuousQuery
spec:
queryLanguage: GQL # or "Cypher" (default)
query: |
MATCH (v:Vehicle)
WHERE v.color = 'Red'
RETURN v.color
GQL-Specific Features:
FILTER - Post-query filtering (like SQL HAVING)LET - Create computed variablesYIELD - Project and rename columnsNEXT - Chain multiple query statementsGROUP BY - Explicit aggregation groupingExample with FILTER (post-aggregation):
MATCH (v:Vehicle)
RETURN v.color AS color, count(v) AS vehicle_count
GROUP BY color
NEXT FILTER vehicle_count > 5
RETURN color, vehicle_count
Common Parser Errors:
wishlist-trending-itemsinventory-low-stock-alertorder-fraud-detectionapiVersion: v1
kind: ContinuousQuery
name: wishlist-trending-items # Descriptive, hyphenated name
spec:
# Specify query language explicitly
queryLanguage: Cypher
# Document the query purpose
# Purpose: Detect trending wishlist items requested by 5+ children in 24h
# Trigger: New WishlistItem events from event hub
# Output: List of trending toy names with request counts
sources:
input:
- wishlist-source # Reference to Source definition
query: |
MATCH (w:WishlistItem)
WHERE drasi.changeDateTime() > datetime() - duration('PT24H')
WITH w.toyName AS toy, count(*) AS requests
WHERE requests >= 5
RETURN toy, requests
apiVersion: v1
kind: Source
name: wishlist-source
spec:
kind: EventHub # or PostgreSQL, CosmosDB, etc.
properties:
connectionString: ${EVENTHUB_CONNECTION_STRING} # Use env vars for secrets
consumerGroup: drasi-consumer
middleware:
- kind: map
my-event-hub:
insert:
- label: WishlistItem # Label used in MATCH clauses
properties:
- name: toyName
- name: childId
- name: priority
apiVersion: v1
kind: Reaction
name: trending-alert-reaction
spec:
kind: SignalR # or Webhook, StoredProc, etc.
queries:
- wishlist-trending-items # Reference to ContinuousQuery
properties:
connectionString: ${SIGNALR_CONNECTION_STRING}
hubName: trending-alerts
drasi apply to a test namespacedrasi logsdrasi apply -f debug-reaction.yaml -n drasi-system
drasi logs reaction debug-reaction -n drasi-system -f
${queryId}:${entityId}:${windowStart}).Replay checklist:
WHERE filters early to reduce per-change workload and avoid backlog growth.If query shows TerminalError:
drasi describe query <name> -n drasi-system for error detailsDebug Steps:
# Check query status
drasi list query -n drasi-system
# Get detailed error information
drasi describe query my-query -n drasi-system
# View reaction logs for output inspection
drasi logs reaction my-reaction -n drasi-system -f
context7 MCP server with library ID: /drasi-project/docsdrasi apply 500 errors on reapplycollect() function implementation (in progress)