Using a Data Query

The Zoomdata JavaScript client library provides functions to query the Zoomdata server for data. This guide uses a method that does not provide event handling for the queries. To assist you in querying for data without handling events, Zoomdata provides:

  • This topic, which includes annotated steps for using a query in your own web app.
  • A simple example of a query used to render a table, with annotated code, discussed in this topic, and available for download at the Developer Zone.
For information about the structure of the query configuration object, see Query Configuration Object.

How a Query Works

The Zoomdata object is used to create a Zoomdata client object. This client is then used to create a query object. To run the query, you pass it and a data processing function to client.runQuery(). The client.runQuery() function retrieves data and passes it to the data processing function.

Steps for Using a Query in Your Web App

These high-level steps for using a query in a web application will guide your work.

  1. Link dependencies
  2. Organize application and security parameters
  3. Configure the query
  4. Code the query
  5. Run the query
  6. Find your data in a data object generated by the query

Linking Dependencies

Using Zoomdata data queries depends on the zoomdata-client.js library version 2.0 or later. You can link to this library on your Zoomdata server at zoomdata/sdk/2.0/zoomdata-client.js. The minified version is found at zoomdata/sdk/2.0/zoomdata-client.min.js.

The example code used in this topic also requires jQuery.js. Your script must have access to this library to use the example.

Organizing Application and Security Parameters

Connecting the web page to your Zoomdata server requires supplying the Zoomdata server with application and security parameters in the form of JavaScript objects. These two objects are themselves bundled together as a single object to be passed to the createClient() method. For example:

	credentials: credentialConfig,
	application: applicationConfig

For more information about the application configuration object, see Application Configuration Object.

For more information about the security configuration object, see Security Configuration Object.

Configuring the Query

Before you can create a query, you must create a query configuration object. This object is used to create a query using the Zoomdata client's member function createQuery(). For example, the query configuration object below gathers from its data source up to 200 productGroup items, sorting them in ascending order and measuring them by their average price, filtering out any groups whose average price is not less than 100.

var queryConfig = {
	tz: 'EST',
	time: { timeField: '_ts' },
	player: {},
	filters: [{ path: 'price', operation: 'LT', value: 100 }],
	groups: [{
		name: 'productGroup',
		limit: 200,
		sort: { dir: 'asc', name: 'productGroup' }
	}, {
		name: 'productCategory',
		limit: 200,
		sort: {dir: 'asc', name: 'productCategory'}
	metrics: [{
		name: 'price',
		func: 'avg' }]

Coding the Query

The createClient() and runQuery() functions are used to create and run a query. The runQuery() function returns a promise, so you can chain then() and done() functions to it.

To code a query:

  1. Instantiate a Zoomdata client if you do not already have one that you want to use.
    	credentials: credentialConfig,
    	application: applicationConfig }).then((client) => { 
         		     // where client is the newly created instance of the client
  2. Use the client’s createQuery() method to create the query. The required parameters are a data source available to the client (based on the server it accesses and its permissions) and a query configuration object.
    client.createQuery({name: 'Real Time Sales'}, queryConfig).then((queryInstance) => { 
    			// resulting queryInstance can be used to query for data from the data source

Running the Query

The Zoomdata client library offers different ways to run the query to gather data. This tutorial uses the client.runQuery() method, which applies a function to each data object resulting from the query. There is also a method, which returns a thread that contains both the data and other messages that are useful for working with data.

To run a query with client.runQuery():

  1. Supply runQuery() with these parameters:
    1. a query, which you can create using the steps found in Coding a Query
    2. a function to execute on each object resulting from the query, which should take one parameter
    client.runQuery( theQuery, function( dataObject ) {
    	console.log( 'Data object returned by query: ', dataObject );
  2. Typically, you should chain a .catch() function to handle errors after the event handling function
    .catch( function( theError ) {
    	console.log( 'Error: ', theError );
The function runQuery() extracts a data object, rather than a single piece of data, from your query and passes it to your data processing function. For more information about finding the data you need in the returned data object, see Full Example.

Full Example

	credentials: credentialConfig,
	application: applicationConfig })
.then(client => {
       client.createQuery({name: 'Real Time Sales'}, queryConfig)
              .then(query => {
                    client.runQuery( query, function( dataObject ) {
				// dataObject contains array of data from back end responses. 
				console.log( 'Data object returned by query: ', dataObject );

Finding Your Data

The runQuery() function returns a data object or more commonly an array of data objects. These objects each have the same structure, which can be predicted by the query configuration and also discovered programmatically.

Structure of the Data Object

Each data object consists of the following objects:

  • current : an object that contains a count value and a metrics object
    • count : indicates the number of rows of data represented in the data object
    • metrics : contains one object for each metric
      	count: 131
      			avg: $23.32
      			avg: $13.16
      • individual metric objects contain a key:value pair. The key is the operation of the metric, such as 'avg' or 'min'. The value is the metric value, for example:
      • The current object above indicates that 131 rows of data are in the queried group, and have an average revenue of $23.32 and average profit of $13.16
  • group : an array listing the groups aggregated in the data object
    • for example
      	0: 'Gaithersburg'
      	1: 'Coffee'
      The groups object above represents rows of data that satisfy both grouping requirements: 'Gaithersburg' and 'Coffee', which, depending on the data set, may represent sales of coffee in Gaithersburg.

Isolating a Piece of Data Manually

If you know the structure of the query in advance, you can reliably anticipate the structure of the data object. The query returns metrics, groups, and fields in the order they are found in the query object.

To verify the order, use a console.log() statement to output to the debugging console a sample data object returned by the query.

Individual elements of the data object can be isolated and used as a JavaScript object. For example, to access the average price in the data object above, use either of the following expressions.




Isolating a Piece of Data Programmatically

You will not always know in advance which metrics, groups, and fields are involved in a data structure. The Query API provides accessor functions to identify programmatically the metrics, groups, and fields involved in a query. These functions are useful in the event that a query is subject to change at runtime. These accessors include:

  • query['metrics'].get()
  • query['groups'].get()
  • query['fields'].get()

Each of the accessors above returns an array of objects with one object for each metric, group, or field, respectively. These objects are structured as they are structured in the query configuration object. For more information about query configuration objects, see Query Configuration Object. In the event that there are no metrics, groups, or fields in the query, that particular accessor will return an empty array.

Using the accessors, you can use the following steps to programmatically iterate through the metrics, groups, or fields used by your data query.

  1. Create an array with the names of metrics, groups, or fields
  2. Use the array to iterate through the returned data objects

Each of these steps is described below in more detail.

To create an array with the names of metrics, groups, or fields:

These steps use metrics as an example. You can also use groups or fields with the same procedure by replacing metrics with groups or fields.

  1. Call query['metrics'].get() and assign the returned array to a variable.
    var metrics = query['metrics'].get();
  2. Iterate through the returned array using its forEach() method. Pass to forEach() an anonymous function to extract the name of each metric and add it to an array of the purpose of storing only the names of metrics.
    var metricNames = [];
    metrics.forEach( function(metric) {
    	metricNames.push( );

These steps combined produce an array containing only the names of the metric objects, in the same order that they appear in both the returned metric object list and in the query configuration object.

To use the array to iterate through the returned data objects:

These steps use metrics as an example. You can also use groups or fields with the same procedure by replacing metrics with groups or fields.

Use the anonymous function to touch each data point and perform on it whatever operation you need.

dataObjectArray.forEach( function(dataObject) {
	console.log( metricName, ' is: ', dataObject['current']['metrics'][metricName]['avg'] );

In the same way, you can gather and automatically process data by field or group.