TQL Cookbook

Lists

List all values of a variable

Problem
List all the values of a variable.

Solution
Use listUnique on the variable:

lu t.e.sv:s:userCountry : exists t.e.sv:s:userCountry

sv:s:userCountry is meant to be a string (s:) session variable (sv:) defined in the bot

List unique inputs to a flow

Problem
List all the different (unique) inputs to a specific flow.

Solution
Use listUnique combined with a constraint on the flow name or flow id:

lu t.e.userInput : t.e.type=="request", t.e2.fname == "User says yes"

Problem
List user input words that are showing a significant positive or negative trend.

Solution
Use the trend transformer and set the cut off values to the appropriate values (recommended values below):

lu t.e.userInputWords, tau, direction, p, z :
    t.e.type == "request",
    trend (max-p="0.05", min-tau="0.2") t.e.userInputWords as (tau, direction, p, z)
order by tau

The trend algorithm is based on the Mann-Kendall trend test, which is a specific implementation of the general Kendall Tau correlation test

List variable values matching a pattern

Problem
List variable values that match a specific pattern, in the case of the example below: country names starting with a capital vowel.

Solution
Use regular expression matching on the variable value:

lu t.e.sv:s:userCountry : t.e.sv:s:userCountry ~= ".[A|E|I|O|U].+"

sv:userCountry is meant to be a string (s:) session variable (sv:) defined in the bot

A quotation mark may be part of a variable value, hence the leading dot in the regex above

List flows coming before safetynet

Problem
List flows that are coming immediately before a safetynet flow.

Solution
Use listUnique and skip-to for controlling the order events:

lu t1.e.fname, t2.e.fname :
    t1.e.pathType=="raise-flow",
    t1.e-{pathType=="raise-flow"}>t2.e,
    t2.e.fname ~= ".*[s|S]afetynet.*"

List review reason values

Problem
List the all the non-empty values of the review reason meta-data variable.

Solution
Use listUnique and regex constraint on the review reason variable:

lu t.e.md:REVIEW_REASON : t.e.md:REVIEW_REASON ~= ".+"

md:REVIEW_REASON is meant to be a metadata variable defined in the solution

List review reason values with user inputs and flow names

Problem
List the all the non-empty values of the review reason meta-data variable, alongside the user input and the flow name.

Solution
Use listUnique and regex constraint on the review reason variable, in combination with user input and flow name:

lu t.e1.userInput, t.e2.fname, t.e3.md:REVIEW_REASON :
    t.e1.type=="request",
    t.e1.userInput ~= ".+",
    exists t.e2.fname,
    t.e3.md:REVIEW_REASON ~= ".+"

md:REVIEW_REASON is meant to be a metadata variable defined in the solution

List negative feedback comments

Problem
List the unique feedback comments that are accompanied by a negative rating.

Solution
Use listUnique with a constraint on the feedback rating variable:

lu t1.e.md:FEEDBACK_COMMENT, t2.e.md:FEEDBACK_RATING :
    t1.e.md:FEEDBACK_COMMENT ~= ".+",
    t2.e.md:FEEDBACK_RATING ~= "negative"

md:FEEDBACK, md:FEEDBACK_RATING, and md:FEEDBACK_COMMENT are meant to be metadata variables defined in the solution.

List user inputs matching a language object condition

Problem
List the user inputs that match a given language object or language object condition.

Solution
Use listUnique with the matches-condition transformer:

lu t.e.userInput :
    t.e.type == "request",
    t.e.userInput matches-condition (solution="en_tlr", condition = "%WHO.FW.LEX + %BE.VB.LEX")

The example above shows that the condition parameter accepts any valid combination of language objects and condition operators. However, the same condition could be rewritten using a single language object: “WHO_IS.PHR”

List language objects matching user inputs

Problem
List the language objects matching every user input. This can be used to analyze how to improve conditions in the solution according to the matching LOBs.

Solution
Use listUnique with the matching-lobs transformer:

lu t.e.userInput, lob, used-words :
    matching-lobs(solution="en_tlr") t.e.userInput as (lob, used-words)

List triggered flows per day from aggregated data

Problem
List the flows that have been triggered in a transaction for aggregated data.

Solution
Use listAll on the aggregated data:

la (a="test") triggeredFlowsIdPerDay

The example above assumes that an aggregator "test" has been created, with the property triggeredFlowsIdPerDay which contains the relevant flow ids

List words matching pattern irrespective of case

Problem
List all user inputs containing "hello" irrespective of case.

Solution
Use listAll on userInputWords with the ~~ operator:

la t.e.userInputWords :
    t.e.type == "request", t.e.userInputWords ~~ "hi"

List inputs going to a particular trigger

Problem
List all inputs going to a particular trigger.

Solution
Use listAll and specify the name of the trigger, combined with skip-constraints:

la t.e1.userInput, t.e2.vname :
    t.e1.type=="request",
    t.e2.vname=="Send SMS",
    t.e1-{pathType=="flow-trigger"}>t.e2

The example is based on a solution that retrieves inputs going to the Send SMS trigger

List answers after a particular trigger

Problem
List all answers after a particular trigger has been activated.

Solution
Use listAll and specify the name of the trigger, combined with skip-constraints:

la t.e1.vname, t.e2.answerText :
    t.e1.pathType=="flow-trigger" ,
    t.e1.vname=="Send SMS",
    t.e1-{type=="response"}>t.e2

The example is based on a solution that retrieves inputs going to the Send SMS trigger

Count and averages

Count the number of dialogues

Problem
Count the number of dialogues/sessions.

Solutions
Use countUnique or countAll on the session id:

cu s.id
ca s.id

Count user inputs

Problem
Count all user inputs.

Solution
Use countAll on the user input (use countUnique to get types rather than tokens):

ca t.e.userInput : t.e.type=="request"

Count variable values

Problem
Count the number of values found in a variable, excluding the default value.

Solution
Use countUnique in combination with a sub-query:

cu x.city :
    x=@(lu t.e.sv:s:userCity as city : t.e.sv:s:userCity ~= "...+")

sv:userCountry is meant to be a string (s:) session variable (sv:) defined in the solution.

Count bot responses

Problem
Count all bot outputs.

Solution
Use countAll on the output text (use countUnique to get types rather than tokens):

ca t.e.answerText :
    t.e.pathType=="output",
    exists t.e.answerText

Calculate mean transaction count for a time period

Problem
Calculate the mean transaction count for a given time period.

Solution
Use the mean prefix in combination with a sub-query:

lu mean x.count as meanCount :
    x=@(lu s.id, s.transactionCount as count : s.beginTime=="2015-03-11")

Calculate mean number of empty inputs for a time period

Problem
Calculate the mean number of empty user inputs for a given time period.

Solution
Use the mean prefix in combination with a sub-query:

lu mean x.count as meanEmptyCount :
    x=@(d date, t.e.userInput :
        t.e.type=="request",
        t.e.userInput == "",
        catd(model="date") s.beginTime as date,
        s.beginTime == in {"2015-03-11".."2015-03-17"})

Calculate mean number of results for aggregated data

Problem
Calculate the mean number of observations per date for aggregated data.

Solution
Use listAll in combination with the mean prefix:

la (a="test") mean count, date

This example assumes that an aggregator "test" with the properties date and count has been created

Frequency lists

To create top N lists from the solutions, use limit, e.g. limit 10 for a top-10 list (when sorted in descending order).

Most frequent user inputs

Problem
Count the user inputs and sort in decreasing order.

Solution
Use distribute and order by count, specify request events:

d t.e.userInput :
    t.e.type=="request",
    t.e.userInput ~= ".+"
order by count desc

Most triggered flows

Problem
Count the triggered flows and sort in decreasing order.

Solution
Use distribute and order by count, specify flow-trigger events:

d t.e.fname :
    t.e.pathType=="flow-trigger" 
order by count desc

Most frequent safetynet inputs

Problem
Count the inputs going to a safetynet and sort in decreasing order.

Solution
Use distribute and order by count, combined search for request and flow-trigger events:

d t.e.userInput :
    t.e.type=="request",
    t.e.userInput ~= ".+",
    t.e2.pathType == "flow-trigger",
    t.e2.fname ~= ".*[s|S]afetynet.*" 
order by count desc

Frequency of variable values

Problem
Count the values of a variable and sort in decreasing order.

Solution
Use distribute and order by count, applied to variable:

d t.e.sv:s:userCountry :
    exists t.e.sv:s:userCountry
order by count desc

sv:s:userCountry is meant to be a string (s:) session variable (sv:) defined in the solution.

The default value of the variable (such as "") is also listed. Use regex matching to require a longer string if "" is to be excluded.

Frequency of flows triggered by a specified input

Problem
Count the flows that are triggered by a specific input and sort in decreasing order.

Solution
Use distribute and order by count, in combination with skip-to:

d t.e1.userInput, t.e2.fname :
    t.e1.type=="request",
    t.e1.userInput ~= ".*hungry.*",
    t.e1-{pathType=="flow-trigger"}>t.e2 
order by count desc

Returns frequency list of user inputs containing "hungry" and triggered flows

Frequency of flow triggers

Problem
Count the number of times flow triggers have been activated and sort in decreasing order.

Solution
Use distribute and order by count, specify flow-trigger events:

d t.e1.fname :
    t.e1.pathType=="flow-trigger",
    exists t.e1.fname 
order by count desc

Frequency of sessions per day or week

Problem
Count the number of sessions per day or week in a time period and sort chronologically by date.

Solution
Use distribute and order by date asc:

d date :
    catd(model="date") s.beginTime as date
order by date asc
d week :
    catd(pattern="yyyy-'w'ww") s.beginTime as week
order by week asc

Frequency of sessions with an input triggering safetynet by day

Problem
Count the number of sessions per day, where at least one input has ended up in the Safetynet.

Solution
Use distribute to count sessions, with a constraint on the flow name:

d date :
    catd(model="date") s.beginTime as date,
    t.e1.type=="request",
    t.e2.fname~=".*[s|S]afetynet.*"

Frequency of triggered flow folders

Problem
Count the number of times the flows from various folders have been triggered and sort in decreasing order.

Solution
Use distribute with folder:

d t.e.folder :
    t.e.pathType=="flow-trigger",
    t.e.folder ~= ".+"
order by count desc

Frequency of traversed safetynet transitions

Problem
Count the number of times the different transitions in the safetynet flow(s) have been logged, and list the names and ids of the transitions sorted in decreasing order.

Solution
Use distribute with the transition path type:

d t.e.vname, t.e.vid :
    t.e.pathType=="transition",
    t.e.vname ~= ".+",
    t.e.fname ~= ".*[S|s]afetynet.*"
order by count desc

Frequency of review reason values

Problem
Count the number of non-empty values of the review reason meta data variable, and sort in decreasing order.

Solution
Use distribute with a regex constraint on the review reason variable:

d t.e.md:REVIEW_REASON :
    t.e.md:REVIEW_REASON ~= ".+"
order by count desc

md:REVIEW_REASON is meant to be a metadata variable defined in the solution

Frequency of feedback rating

Problem
Count the number of different feedback ratings, and sort in decreasing order.

Solution
Use distribute on the feedback rating variable:

d t.e.md:FEEDBACK_RATING :
    t.e.md:FEEDBACK_RATING ~= ".+"
order by count desc

md:FEEDBACK_RATING is meant to be a metadata variable defined in the solution

Frequency of inputs matching A OR B

Problem
Count user inputs matching one of two possible values (or more).

Solution
Use distribute in combination with set constraints to emulate a logical OR condition:

d t.e.userInput :
    t.e.type == "request",
    t.e.userInput ~= in {"A", "B"}

Was this page helpful?