Inside Infostore – Part II: Modules and Paths
Wednesday, July 8th, 2009Back in April, in the first installment of our Inside Infostore series, we looked at the general structure of the Infostore repository for real-time caller behavior analysis and answered a number of interesting questions on the basis of the Call Detail Record table VOLDDLGSTS alone. This time, we’ll take a look at Module information available within Infostore. It provides valuable insight into how callers use your application – which parts they visit, which parts they skip, and exactly how they get to where they end up.
Modules
Module objects in the Voxeo VoiceObjects framework provide a “wrapper” for applications or sub-applications within a bigger one such as a self-service portal. The Prime Insurance sample provides a good model, as shown in its main menu:

A separate Module object encapsulates each of the five branches, as well as the overall application. Each Module defines inheritable event handling, navigation using hyperlinks, and additional application settings.
More information on the Module object can be found within the Object Reference. Best practices in structuring your application using Modules are discussed in the Design Guide. Both are highly recommended additional reading.
Module Tables
Module information is stored within Infostore in five different tables: VOLDMODULE, VOLDMODSEQ, VOLDMODSET, VOLDRELMSQ, and VOLDSUBSEQ. Other tables, such as VOLDDLGSTS, refer to them through surrogate IDs.
VOLDMODULE contains general lookup information on each Module object such as its name, modification timestamps, and key settings.
Data in this table is updated with each deployment or redeployment. In addition to the “real” Module objects, the table also contains an entry for “[End of Dialog]“, which is used to indicate the end of the dialog (as you may have guessed).
VOLDMODSEQ contains an entry for each sequence of Module objects that has been traversed within a call. So e.g. when somebody calls the Prime Insurance application shown above, selects the car insurance branch from the main menu, and then afterwards also inquires about life insurance, there would be an entry “Prime Insurance Portal,Car Insurance,Life Insurance”.
Data is entered into this table as necessary whenever a new sequence is observed in a call.
VOLDMODSET is similar in that it contains one entry for each set of Module objects that has been visited within a call. Multiple sequences may lead to the same set, and each sequence entry in VOLDMODSEQ contains a pointer to the respective set entry in VOLDMODSET. The set entry is sorted alphabetically, so for the same call example as above the set entry would be “Car Insurance,LifeInsurance,Prime Insurance Portal”.
Data is entered into this table as necessary whenever a new set is observed in a call. Since the sequence entry references the corresponding set entry, the set entry is made first.
VOLDRELMSQ maps individual Module objects to module sequences and the positions at which they occur within these sequences. In the example there would be three separate entries mapping Module “Prime Insurance Portal” to the first position in the sequence, “Car Insurance” to the second position, and “Life Insurance” to the third.
Data is entered into this table as necessary whenever a new sequence is observed in a call.
Finally, VOLDSUBSEQ contains a break-down of Module sequences into their constituent sub-sequences. This information is needed for reports such as the dominant path analysis referred to below. In our example this will result in the following six sub-sequences including the end marker ”[End of Dialog]” mentioned above:
-
Prime Insurance Portal,Car Insurance,Life Insurance,[End of Dialog]
-
Prime Insurance Portal,Car Insurance,Life Insurance
-
Prime Insurance Portal,Car Insurance
-
Car Insurance,Life Insurance,[End of Dialog]
-
Car Insurance,Life Insurance
-
Life Insurance,[End of Dialog]
Data is entered into this table as necessary whenever a new sequence is observed in a call.
Taken together, these five tables can be utilized to gain insight into how callers navigate through your applications. The next two sections explore a number of sample questions.
Basic Orientation
As in part I, the SQL statements shown below have been tested using Microsoft SQL Server. They are meant to be indicative of specific types of information and are formulated for readability rather than performance. Entries in all tables mentioned here belong to specific services identified by a unique ID, the VSC_SID. In all of the samples we assume this SID to be known and fixed. It can be retrieved like this:
select vsc_sid from voldvscobj where vsc_refid=’<VSN of service>’ and is_current=1
Finally, the SQL statements used here operate on the “raw” Infostore tables. For Analyzer, there is an additional view layer that adjusts localization and performs a few mappings that usually aren’t relevant here.
With these preliminaries out of the way, here are a few high-level questions that can be answered easily on the basis of the Module set and sequence entries as well as the references in the VOLDDLGSTS table we looked at before:
-
How many different sets / sequences do callers visit?
Obviously this is about the simplest question you can ask regarding sets and sequences, but it does already give you a high-level idea of how callers utilize an application.
select count(*) from voldmodset where vsc_sid=SID
select count(*) from voldmodseq where vsc_sid=SID
-
What is the ratio between sets and sequences?
This ratio is a rough measure of variability between different calls (and callers). When it is close to 1, callers visit the same places in roughly the same way. When it is significantly bigger than 1, different calls visit the same places in significantly different ways. Keep in mind, however, that this value depends on application design at least as much as it depends on caller choices.
select (select count(*) from voldmodseq where vsc_sid=SID) / (select count(*) from voldmodset where vsc_sid=SID)
-
Which percentage of calls visits a certain sub-application?
Different choices within a self-service portal will attract callers to differing extents. In our example we want to know the percentage of calls that visit the “Life Insurance” branch of the Prime Insurance Portal.
select 100.0*count(*)/(select count(*) from volddlgsts where vsc_sid=SID) from volddlgsts where mod_set_sid in (select mod_set_sid from voldmodset where mod_set_name like ‘%Life Insurance%’) and vsc_sid=SID
-
How often does each Module object occur in sequences?
Module sequences will contain individual Module objects in different numbers, which is indicative of their respective importance in call flows.
select count(*) as cnt, m.mod_name from voldrelmsq r inner join voldmodule m on (r.mod_sid = m.mod_sid and m.mod_sid>0 and r.vsc_sid=SID) group by m.mod_name order by cnt desc
-
What is the most / least visited sub-application within my application portal?
If your application is e.g. a banking self-service portal offering sub-applications such as balance checking, making transfers, and brokerage transactions, then you will want to know if 90% of your callers really only want to check their account balance at the end of the month. Note that while this question is similar to the preceding one, here we’re dealing with numbers of actual calls as opposed to just occurrences of Module objects in sequences.
select m.mod_name, count(dlg_id) as callCount from voldmodule m inner join ((select distinct mod_seq_sid, mod_sid from voldrelmsq) as r inner join volddlgsts as s on r.mod_seq_sid = s.mod_seq_sid and vsc_sid=SID) on r.mod_sid = m.mod_sid and m.vsc_sid=SID group by m.mod_name order by callCount desc
-
What is the average time spent in each Module visited?
This simple query does, of course, only give you a very rough global estimate – but it can give a hint on whether the “size” of your Modules is reasonable. If the average time spent in a Module is in the order of minutes, you may want to add more structure to your application by adding Module objects in strategic places to obtain a better resolution.
select avg(dlg_call_dur_ms/(1000.0*no_modules)) from volddlgsts where no_modules>0 and vsc_sid=SID
-
Which Module scopes do callers typically hang up in?
Knowing where in the application callers hang up can validate (or invalidate) assumptions about caller behavior.
select count(d.dlg_id) as cnt, m.mod_name as modname from volddlgsts d, voldmodule m where m.mod_sid=d.last_module_sid and d.dlg_exit_type_id=16 and d.last_module_sid>-1 and d.vsc_sid=SID group by m.mod_name order by cnt desc
Paths
VoiceObjects Analyzer contains a Dominant Path Analysis report that shows in significant detail how callers navigate through your application, and which choices they predominantly make whenever there is a fork in the road.

While this report is too complex to replicate fully in manual SQL, we can answer a number of related questions here:
-
Which paths have callers taken to get from one Module to another?
Different paths can lead to the same destination, and to optimize the flow of an application it is very relevant to look at the various paths callers take to get from one place to another. In our example we want to find all the different paths that lead from the Module object with Reference ID “LifeInsurance” to the one with Reference ID “CarInsurance”.
select distinct mod_seq_refid as paths from voldsubseq where mod_start_sid=(select mod_sid from voldmodule where mod_refid=’LifeInsurance’ and vsc_sid=SID) and mod_end_sid=(select mod_sid from voldmodule where mod_refid=’CarInsurance’ and vsc_sid=SID) and vsc_sid=SID
-
Which Modules are often visited together?
As a mirror to the first question, it is also of interest to see which Modules are often visited alongside a given Module. In terms of online shopping, this is a bit like saying “customers who bought this item also liked these other products”.
select m1.mod_name as name1, m2.mod_name as name2 from voldmodule m1, voldmodule m2 where m1.mod_sid<m2.mod_sid and m1.mod_sid>0 and m2.mod_sid>0 and m1.vsc_sid=SID and m2.vsc_sid=SID and exists (select * from (select * from voldrelmsq where mod_sid=m1.mod_sid and vsc_sid=SID) as rel1 inner join (select * from voldrelmsq where mod_sid=m2.mod_sid and vsc_sid=SID) as rel2 on rel1.mod_seq_sid = rel2.mod_seq_sid)
-
Which Modules occur as immediate predecessors of a given Module object in sequences?
Expectations about how to use a certain sub-application are driven by the other places the caller has previously been to during the call. Therefore it is relevant to look at the predecessor Module object. In our example, we want to find out which places callers come from just before they enter the “Car Insurance” sub-application within Prime Insurance.
select distinct mod_start_name as predecessor from voldsubseq where mod_end_sid=(select mod_sid from voldmodule where mod_name=’Car Insurance’ and vsc_sid=SID) and mod_subseq_count=0 and vsc_sid=SID
And with this, we’ve reached the end of our path for today.
In the next installment we’ll dig one level deeper and look at the detailed information that is written for each caller interaction in the input state table VOLDDSSEQ. In the meantime, we’d love to get your feedback. Just leave a comment below!










