ワンクリックで
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)