| name | analytics-nodejs |
| summary | Couchbase Analytics Service (CBAS) for Node.js — run OLAP queries, window functions, and external data links without impacting operational workloads (Server 6.x–7.x; use columnar-analytics for Server 8+) |
| description | Couchbase Analytics Service (CBAS) for Node.js — run OLAP queries, window functions, and external data links without impacting operational workloads (Server 6.x–7.x; use columnar-analytics for Server 8+) |
| compatibility | Node.js SDK 4.x. Requires couchbase>=4.0. |
| metadata | {"last_verified":"2026-05","min_server_version":"6.0","deprecated_by":"columnar-analytics","deprecated_since":"8.0","max_server_version":"7.6","handoff":[{"condition":"user asks about SQL++ queries","skill":"server-querying-nodejs"},{"condition":"user is upgrading to Server 8.x and wants the columnar engine","skill":"columnar-analytics"},{"condition":"user wants to write results back to operational collections transactionally","type":"variant","skill":"transactions-nodejs"}]} |
Couchbase Analytics — Node.js
Version disambiguation: This skill covers Couchbase Server 6.x–7.x (legacy CBAS). If the user mentions Server 8, Couchbase 8, or the columnar engine, route to columnar-analytics instead. If the server version is unknown, ask before proceeding.
Analytics runs OLAP queries on a shadow copy of your data, isolated from KV and Query Service workloads.
Setup
CREATE DATAVERSE myapp IF NOT EXISTS;
USE myapp;
CREATE ANALYTICS COLLECTION orders ON `myapp`.`_default`.`orders` IF NOT EXISTS;
SDK Query
const result = await cluster.analyticsQuery(
'SELECT country, COUNT(*) AS cnt FROM airlines GROUP BY country ORDER BY cnt DESC',
{ timeout: 300_000 }
);
for (const row of result.rows) console.log(row);
Parameterized Query
const result = await cluster.analyticsQuery(
'SELECT * FROM orders WHERE status = $status',
{ parameters: { status: 'pending' }, timeout: 300_000 }
);
Window Functions
const result = await cluster.analyticsQuery(
`SELECT name, country, stars,
RANK() OVER (PARTITION BY country ORDER BY stars DESC) AS rank_in_country
FROM hotels
WHERE stars IS NOT MISSING`
);
for await (const row of result.rows) {
console.log(row);
}
External Datasets
const result = await cluster.analyticsQuery(
'SELECT * FROM `external-dataset` LIMIT 100'
);
External datasets are created via the Analytics Service UI or REST API and appear as queryable collections.
Troubleshooting
| Error | Cause | Fix |
|---|
23000 / DatasetNotFoundException | Dataset not created | Run CREATE ANALYTICS COLLECTION or check name |
| Query timeout | Large scan, no limit | Add LIMIT, increase timeout option |
| Stale data | Replication lag | Expected — Analytics is eventually consistent |
Analytics vs Query Service: See shared/server/analytics-vs-query.md for the full comparison, setup steps, and common errors.
Writing Results Back
Use transactions for atomic write-back, or individual KV upserts for non-atomic bulk writes.
const result = await cluster.analyticsQuery(
'SELECT id, total FROM orders WHERE status = "complete"'
);
const collection = cluster.bucket('myapp').defaultCollection();
for (const row of result.rows) {
await collection.upsert(`summary::${row.id}`, { total: row.total });
}
For atomic multi-document write-back, wrap in a transaction — see transactions-nodejs.
When to Use Analytics vs Query Service
| Scenario | Use |
|---|
| Full collection scan + complex aggregation | Analytics |
| OLTP point lookups | Query Service |
| Report needing many GSI indexes | Analytics |
| Real-time data (< 1s staleness) | Query Service |