+
    Parallel data management for complex queries over many records, using a familiar SQL++ syntax.

    This page covers Couchbase’s traditional Analytics Service, for long-running queries. A separate, as-a-service offering — Capella columnar — offers real-time analytics.

    Capella Columnar SDKs

    SDKs for Capella Columnar — Couchbase’s analytical database (RT-OLAP) for real time apps and operational intelligence — are in development, and will be arriving first for the Java, Node.js, and Python platforms.

    For complex and long-running queries, involving large ad hoc join, set, aggregation, and grouping operations, Couchbase Data Platform offers the Couchbase Analytics Service (CBAS). This is the analytic counterpart to our operational data focussed Query Service.

    The analytics service is available in Capella operational or the Enterprise Edition of self-managed Couchbase Server.

    Getting Started

    After familiarizing yourself with our introductory primer, in particular creating a dataset and linking it to a bucket to shadow the operational data, try Couchbase Analytics using the C++ SDK. Intentionally, the API for analytics is very similar to that of the query service.

    Before starting, here’s all imports used in the following examples:

    #include <couchbase/cluster.hxx>
    #include <couchbase/fmt/error.hxx>
    
    #include <tao/json/to_string.hpp>

    Here’s a complete example of doing an analytics query and handling the results:

    std::string query{ R"(SELECT "hello" AS greeting)" };
    auto [err, res] = cluster.analytics_query(query).get();
    if (err) {
        fmt::println("Got an error doing analytics query: {}", err);
    } else {
        auto rows = res.rows_as_json();
        for (const auto& row : rows) {
            fmt::println("row: {}", tao::json::to_string(row));
        }
    }

    Let’s break this down. First, we get the results in the form of a std::pair<couchbase::error, couchbase::analytics_result>.

    An analytics_result contains various things of interest, such as metrics, but the main thing we’re interested in are the rows (results). They’re fetched with a rows_as_json call.

    We check explicitly for an error which indicates something went wrong during the analytics query call. Please see Error Handling for details.

    Here we’re fetching rows converted into JSON, but as with SQL++ (formerly N1QL) there’s many more options available. Rows can be returned as JSON representations from multiple third party C++ libraries, directly as a user defined class, and more. Please see JSON Libraries for full details.

    Finally, we iterate through the rows.

    Queries

    A query can either be simple or be parameterized. If parameters are used, they can either be positional or named. Here is one example of each:

    std::string query{ R"(SELECT airportname, country FROM airports WHERE country = ?)" };
    auto options = couchbase::analytics_options().positional_parameters("France");
    auto [err, res] = cluster.analytics_query(query, options).get();
    std::string query{ R"(SELECT airportname, country FROM airports WHERE country = $country)" };
    auto options = couchbase::analytics_options().named_parameters(std::pair{ "country", "France" });
    auto [err, res] = cluster.analytics_query(query, options).get();

    Additional Parameters

    The handful of additional parameters are illustrated here:

    std::string query{ R"(SELECT airportname, country FROM airports WHERE country = "France")" };
    auto options = couchbase::analytics_options()
             // Ask the analytics service to give this request higher priority
             .priority(true)
             // The client context id is returned in the results, so can be used by the
             // application to correlate requests and responses
             .client_context_id("my-id")
             // Override how long the analytics query is allowed to take before timing out
             .timeout(std::chrono::milliseconds(90000));
    
    auto [err, res] = cluster.analytics_query(query, options).get();

    Metadata

    analytics_result::meta_data() contains useful metadata, such as elapsedTime, and resultCount:

    std::string query{ R"(SELECT airportname, country FROM airports WHERE country = "France")" };
    auto [err, res] = cluster.analytics_query(query).get();
    
    if (err) {
        fmt::println("Got an error doing analytics query: {}", err);
    } else {
        auto rows = res.rows_as_json();
        for (const auto& row : rows) {
            fmt::println("row: {}", tao::json::to_string(row));
        }
    
        auto elapsed_time = res.meta_data().metrics().elapsed_time();
        auto result_count = res.meta_data().metrics().result_count();
        auto error_count = res.meta_data().metrics().error_count();
    }