Teneo Developers

Teneo Query Language Cookbook

Lists

List all values of a variable

Use listUnique on the variable:

tql

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

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

List unique inputs to a flow

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

tql

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

List user input words showing positive or negative trend

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

tql

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

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

For this example, list country names starting with a capital vowel.

Use regular expression matching on the variable value:

tql

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

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 immediately preceding safetynet

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

tql

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

List review reason meta-data values

Use listUnique and regex constraint on the review reason variable:

tql

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

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

List review reason meta-data values with user inputs and flow names

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

tql

1lu t.e1.userInput, t.e2.fname, t.e3.md:REVIEW_REASON :
2    t.e1.type=="request",
3    t.e1.userInput ~= ".+",
4    exists t.e2.fname,
5    t.e3.md:REVIEW_REASON ~= ".+"
6

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

List negative feedback comments accompanied by a negative rating

Use listUnique with a constraint on the feedback rating variable:

tqltql

1lu t1.e.md:FEEDBACK_COMMENT, t2.e.md:FEEDBACK_RATING :
2    t1.e.md:FEEDBACK_COMMENT ~= ".+",
3    t2.e.md:FEEDBACK_RATING ~= "negative"
4

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

Use listUnique with the matches-condition transformer:

tql

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

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”. Note also that this query only works if a solution "en_tlr" has been associated with the log data.

List language objects matching user inputs

This can be used to analyze how to improve conditions in the solution according to the matching LOBs.

Use listUnique with the matching-lobs transformer:

tql

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

Note that this query only works if a solution "en_tlr" has been associated with the log data.

List triggered flows per day from aggregated data

Use listAll on the aggregated data:

tql

1la (a="test") triggeredFlowsIdPerDay
2

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

In this case, list all user inputs containing "hello" irrespective of case.

Use listAll on userInputWords with the ~~ operator:

tql

1la t.e.userInputWords :
2    t.e.type == "request", t.e.userInputWords ~~ "hello"
3

List inputs going to a particular trigger

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

tql

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

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

List answers after a particular trigger

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

tql

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

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

Count and averages

Count the number of dialogues

Use countUnique or countAll on the session id:

tql

1cu s.id
2

tql

1ca s.id
2

Count user inputs

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

tql

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

Count number of values found in a variable

Use countUnique in combination with a sub-query:

tql

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

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

Count bot responses

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

tql

1ca t.e.answerText :
2    t.e.type=="response",
3    exists t.e.answerText
4

Calculate mean transaction count for a time period

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

tql

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

Calculate mean number of empty inputs for a time period

Use the mean prefix in combination with a sub query:

tql

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

Calculate mean number of results for aggregated data

Use listAll in combination with the mean prefix:

tql

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

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

Use distribute and order by count, specify request events:

tql

1d t.e.userInput :
2    t.e.type=="request",
3    t.e.userInput ~= ".+"
4order by count desc
5

Most triggered flows

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

tql

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

Most frequent safetynet inputs

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

tql

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

Frequency of variable values

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

Use distribute and order by count, applied to variable:

tql

1d t.e.sv:s:userCountry :
2    exists t.e.sv:s:userCountry
3order by count desc
4

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

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

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

tql

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

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

Frequency of flow triggers

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

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

tql

1d t.e1.fname :
2    t.e1.pathType=="flow-trigger",
3    exists t.e1.fname 
4order by count desc
5

Frequency of sessions per specified time period

Count the number of sessions per e.g. day or week and sort chronologically by date.

Use distribute and order by date asc:

tql

1d date :
2    catd(model="date") s.beginTime as date
3order by date asc
4

tql

1d week :
2    catd(pattern="yyyy-'w'ww") s.beginTime as week
3order by week asc
4

Frequency of sessions with an input triggering Safetynet by day

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

tql

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

Frequency of triggered flow folders

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

Use distribute with folder:

tql

1d t.e.folder :
2    t.e.pathType=="flow-trigger",
3    t.e.folder ~= ".+"
4order by count desc
5

Frequency of traversed Safetynet transitions

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.

Use distribute with the transition path type:

tql

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

Frequency of review reason values

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

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

tql

1d t.e.md:REVIEW_REASON :
2    t.e.md:REVIEW_REASON ~= ".+"
3order by count desc
4

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

Frequency of feedback rating

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

Use distribute on the feedback rating variable:

tql

1d t.e.md:FEEDBACK_RATING :
2    t.e.md:FEEDBACK_RATING ~= ".+"
3order by count desc
4

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

Frequency of inputs matching A OR B

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

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

tql

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