| name | analytics-java |
| summary | Couchbase Analytics Service (CBAS) for Java — 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 Java — 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 | Java SDK 3.x. Requires com.couchbase.client:java-client:3.x. |
| 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-java"},{"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-java"}]} |
Couchbase Analytics — Java
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 an Analytics Collection
CREATE DATAVERSE myapp IF NOT EXISTS;
USE myapp;
CREATE ANALYTICS COLLECTION orders ON `myapp`.`_default`.`orders` IF NOT EXISTS;
SDK Query
import com.couchbase.client.java.analytics.AnalyticsOptions;
import com.couchbase.client.java.analytics.AnalyticsResult;
import java.time.Duration;
AnalyticsResult result = cluster.analyticsQuery(
"SELECT country, COUNT(*) AS cnt FROM airlines GROUP BY country ORDER BY cnt DESC",
AnalyticsOptions.analyticsOptions().timeout(Duration.ofMinutes(5))
);
result.rowsAsObject().forEach(row -> System.out.println(row));
Parameterized Query
AnalyticsResult result = cluster.analyticsQuery(
"SELECT * FROM orders WHERE status = $status AND total > $minTotal",
AnalyticsOptions.analyticsOptions()
.parameters(JsonObject.create().put("status", "pending").put("minTotal", 100))
);
Reactive API
cluster.reactive().analyticsQuery(
"SELECT country, COUNT(*) AS cnt FROM airlines GROUP BY country",
AnalyticsOptions.analyticsOptions().timeout(Duration.ofMinutes(5))
).flatMapMany(result -> result.rowsAsObject())
.subscribe(row -> System.out.println(row));
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.
AnalyticsResult result = cluster.analyticsQuery(
"SELECT id, total FROM orders WHERE status = \"complete\""
);
ReactiveCollection collection = cluster.bucket("myapp").defaultCollection().reactive();
result.rowsAsObject().forEach(row ->
collection.upsert("summary::" + row.getString("id"),
JsonObject.create().put("total", row.getDouble("total")))
.block()
);
For atomic multi-document write-back, wrap in a transaction — see transactions-java.
When to Use Analytics vs Query Service
| Scenario | Use |
|---|
| Full collection scan + complex aggregation | Analytics |
| OLTP — point lookups, small result sets | Query Service |
| Report that would need many GSI indexes | Analytics |
| Real-time data (< 1s staleness) | Query Service |