Query your Dataset with the Wave Apex SDK

Query your data in Wave from any Apex class. Construct well-formed queries using the query builder. The Wave Apex SDK makes using Wave from Apex much easier.

Is your company one of the gazillion making use of custom code in Apex, the server-side programming language for Force.com? Would you like it to be easier to query data in Wave directly from your Apex code? Say hello to the Wave Apex SDK and send well-formed SAQL queries to Wave.

This first phase of the Wave Apex SDK lets developers build SAQL queries and execute them in the security context of the logged-in user, ensuring that security settings are honored. API versioning is supported to avoid breaking applications as the SDK evolves. The SDK also offers Wave.InvalidParameterException to help catch bad values supplied to the class methods.

Digging Deeper


At its simplest, use the executeQuery function (exposed through the ConnectApi namespace) to pass a SAQL query from an Apex page to Wave, and get a response in the form of JSON. For example, this sample sends ‘your SAQL query’ to Wave.

String query = '[your SAQL query]';     
ConnectApi.LiteralJson result =  ConnectApi.Wave.executeQuery(query);
String response = result.json;

Sending queries like this is very useful, but relies on the developer coding well-formed SAQL queries. Wouldn’t it be great if a class constructed the queries for you?


Exposed through the Wave namespace, the QueryBuilder class is the most convenient, preferred, and safest way to construct a SAQL query string for execution. It’s not an exhaustive implementation of all possible SAQL queries—so sometimes you need to write your own—but it does cover the vast majority of use cases, including:

  • load dataset statement

  • foreach statement

  • group statement

  • order statement

  • limit statement

  • filter statement

  • functions such as min, max, count, avg, unique, as, sum

Use QueryBuilder and its associated classes, Wave.ProjectionNode and Wave.QueryNode, to incrementally build your SAQL statement. For example:

Wave.ProjectionNode[] projs = new Wave.ProjectionNode[]{
ConnectApi.LiteralJson result = Wave.QueryBuilder.load('0FbD00000004DSzKAM', '0FcD00000004FEZKA2')
  .group(new String[]{'State', 'City'})
String response = result.json;


QueryBuilder is the core of this first phase of the Wave Apex SDK, so let’s take a closer look. Here’s a simple count query.

Wave.ProjectionNode[] projs = new Wave.ProjectionNode[]{Wave.QueryBuilder.count().alias('c')};
String query = Wave.QueryBuilder.load('datasetId', 'datasetVersionId').group().foreach(projs).build('q');

The resulting SAQL query looks like this:

q = load "datasetId/datasetVersionId";
q = group q by all;
q = foreach q generate count as c;

Here’s a more complex example that uses a union statement.

Wave.ProjectionNode[] projs = new Wave.ProjectionNode[]{Wave.QueryBuilder.get('Name'), Wave.QueryBuilder.get('AnnualRevenue').alias('Revenue')};
Wave.QueryNode nodeOne = Wave.QueryBuilder.load('datasetOne','datasetVersionOne').foreach(projs);
Wave.QueryNode nodeTwo = Wave.QueryBuilder.load('datasetTwo', 'datasetVersionTwo').foreach(projs);
String query = Wave.QueryBuilder.union(new List<Wave.QueryNode>{nodeOne, nodeTwo}).build('q');

The resulting SAQL query has two projection streams, qa and qb.

qa = load "datasetOne/datasetVersionOne";
qa = foreach q generate Name,AnnualRevenue as Revenue;
qb = load "datasetTwo/datasetVersionTwo";
qb = foreach q generate Name,AnnualRevenue as Revenue;
q = union qa, qb;


For more information on using the Wave Apex SDK, see the Apex Developer Guide and the Wave SDK Developer Guide.