Iterating with Nested Tables

When you are iterating over a table, or performing a multi-get operation, by default only rows are retrieved from the table on which you are operating. However, you can use The options object for the retrieval method to specify that parent and child tables are to be retrieved as well.

When you do this, parent tables are retrieved first, then the table you are operating on, then child tables. In other words, the tables' hierarchical order is observed.

The parent and child tables retrieved are identified using a text array, which is then provided to the options object's includedTables property.

When operating on rows retrieved from multiple tables, it is your responsibility to determine which table the row belongs to.

For example, suppose you create a table with a child and grandchild table like this:

CREATE TABLE prodTable (
    prodType STRING,
    typeDescription STRING,
    PRIMARY KEY (prodType)
) 
CREATE TABLE prodTable.prodCategory (
    categoryName STRING,
    categoryDescription STRING,
    PRIMARY KEY (categoryName)
) 
CREATE TABLE prodTable.prodCategory.item (
    itemSKU STRING,
    itemDescription STRING,
    itemPrice FLOAT,
    vendorUID STRING,
    inventoryCount INTEGER,
    PRIMARY KEY (itemSKU)
) 

With tables containing data like this:

In the following example, notice that we identify which table we are displaying by examining the ReturnRow's table property.

...
// Store handle configuration and open skipped for brevity
...

store.on('open', function () {
   console.log('Store opened');

   // Using an empty primary key for
   // this iteration
   var key = {}; 

   // Identify the child tables to include
   // in the iteration.
   var includeTables = ['prodTable.prodCategory', 
                        'prodTable.prodCategory.item'];

   store.tableIterator('prodTable', key, {
                includedTables: includeTables
           },
   function (err, iterator) {
        if (err)
            throw err;
        else { 

            // Configure Iterator event done
            iterator.on('done', function() {
                store.close();
            }); 

            console.log("Retrieved rows:");

            iterator.forEach(function (err, retRow) {
                if (err)
                    throw err;
                else { 
                    // It is necessary for our code to
                    // identify which table we are 
                    // displaying.
                    if (retRow.table == 'prodTable') {
                        console.log('\n');
                        console.log('Type: ' +
                            retRow.row.prodType);
                        console.log('Description: ' +
                            retRow.row.typeDescription);

                    } else if (retRow.table == 
                            'prodTable.prodCategory') {
                        console.log('\tCategory: ' +
                                    retRow.row.categoryName);
                        console.log('\tDescription:  ' +
                                    retRow.row.categoryDescription);
                    } else {
                        console.log('\t\tSKU: ' +
                            retRow.row.itemSKU);
                        console.log('\t\tDescription: ' +
                            retRow.row.itemDescription);
                        console.log('\t\tPrice: ' +
                            retRow.row.itemPrice);
                        console.log('\t\tVendor UID: ' +
                            retRow.row.vendorUID);
                        console.log('\t\tInventory Count: ' +
                            retRow.row.inventoryCount);
                        console.log('\n');
                    } 
                }   
            }); 
        }   
   }); 
}).on('close', function() {
    console.log('Store closed.');
}).on('error', function(error) {
    console.log(error);
});
store.open();