Data Hierarchy
Property
Sessions contain huge numbers of data and properties. A user input is a property, as is the name of a triggered flow, or the contents of a set variable, to name a few examples. In other words, properties are the basic queryable elements of session logs and a fundamental part of each query.
The properties that you can query are:
- Standard properties (of a session, transaction, or event)
- Global Variables
- Flow Variables
- Metadata
- Annotations
- Request Parameters
If you use the session viewer to examine a session, the right sidebar shows a scrollable list of all the available properties for that session.

One of the standard properties belonging to sessions is beginTime, which you can use to call up sessions that ran on a particular date or range of dates. The table below shows properties that are commonly used in queries. It is by no means exhaustive.
| Property | Description |
|---|---|
beginTime | The date and time the session began |
userInput | The text of the user input |
fname | The name of the flow that triggered |
vname | The name of the node (vertex) within a flow |
outputText | The text of an output node that was traversed |
answerText | The sum of all the output texts that make up the response |
Session
A session is a complete log of a conversation a user had with your bot. At the simplest level, it's a record that reads like a script of the user questions that drive the conversation and the corresponding responses made by the bot. But there's more to a session than just that; a session collects every detail of what happened from the beginning to the end of the conversation, recording not only how the bot responded, but also how that response was arrived at. Each session is logged with a unique session ID to make it easy to find in the Log Data Source viewer.
A session is made up of the following:
- Session properties (id, beginTime, transactionCount and other information about the session)
- Metadata
- Global variables
- A collection of all the transactions
Referencing session properties
TQL by itself does not know where to find the session properties, so when writing a query you have to add a session prefix to put the reference into perspective. For example, to access the session's ID, you would write session.id or s.id for short. The transaction count would be written as s.transactionCount and so on. A query to show all the session IDs along with the transaction count would look like this: listAll s.id, s.transactionCount. You can find out more about the different TQL commands on the Command page in the Query Syntax section on the left.
Session properties

Some properties often used in queries are:
| Property | Description |
|---|---|
| s.id | A unique identifier for a particular session |
| s.beginTime | A timestamp of when the session began |
| s.transactionCount | The number of transactions during the session, including the greeting |
Global variables
Global variables are generally logged as part of the transaction in which they were changed. Exceptions to this are global variables that change during the End dialog script, which is not associated with an actual transaction. This is an easy way to set up queries for end values of important global variables. For example, let's say you counted the number of times a user input ran into the Safetynet. In an End dialog script, you save that variable to itself or to a new variable:

In the LDS viewer, the variable is listed as a global variable at the session level.
Now in TQL you can pull out sessions in which the Safetynet became active only once, or run a distribution to find sessions with higher usage of the Safetynet. Please refer to the TQL manual for the exact syntax to use when querying variables.
Transaction
When a user asks a question, the bot responds; we refer to this process as a transaction, but a transaction is more than that. A transaction records the entire process of how the bot came to respond the way it did. More specifically, a transaction holds everything that happens from the point that a user input is received to the time the bot's response is returned.
Transactions contain the following components:
- Transaction properties
- A list of events of the following types:
- Request
- Path
- Response
Common transaction properties include:
| Property | Description |
|---|---|
| t.id | Unique identifier for transaction, actually the session ID appended with the transaction index |
| t.duration | The amount of processing time from the beginning to the end of the transaction |
| t.index | The index of the transaction, starting with '0' for the first transaction |
| t.time | A timestamp for the transaction |
Referencing transaction properties
Referring to transaction properties in queries needs to be done with a transaction prefix. So if you want to view transaction IDs associated with a particular user input, you would reference the ID as transaction.id or t.id for short. The index property t.index is also useful in locating consecutive transactions, as it will be demonstrated further on in this page.
Note: the transaction ID is the session ID with the number of the transaction appended as a suffix. So if the session ID is B436C752217057D239BD04B5E55FDFF3 the transaction ID of the initial transaction is B436C752217057D239BD04B5E55FDFF3_0 and so on.
Referencing multiple transactions
For cases where it is often necessary to refer to multiple different transactions in a query. Instead of using the t.index you can add an additional identifier to distinguish the references like numbers, e.g. t1.index, t2.index, etc.
This kind of notation is fundamental to Teneo Query Language, so it is important to understand exactly what the identifiers mean. If you refer to properties of t1, e.g. t1.id and t1.index, the concerned properties must come from the same transaction. If you use t1.id and t2.index in your query, the concerned properties do not have to come from the same transaction, but they may.
The numbers in the identifier has nothing to do with order of occurrence. Think of the identifiers as symbolic names. Using t1 and t2 in a query can have the following options:
- t1 does not have to be the first transaction in the session
- t2 can occur before t1
- t1 and t2 may not be consecutive
- t1 and t2 can be the same transaction
- t1 and t2 can be different transactions
You can, however, add additional Constraints to your query to assure that 't1' and 't2' do have specific locations in the session relative to each other. This table shows some ways to do it:
| Transaction identifiers | Constraint | Meaning |
|---|---|---|
| t1, t2 | t1.id != t2.id | t1 and t2 must be different transactions |
| t1, t2 | t1.index == t2.index - 1 | t2 must immediately follow t1 |
| t1, t2 | t1.index < t2.index | t1 must occur sometime before t2 |
Let us look at some simple queries for this brief session. There are two transactions, the first with index '0', the second with index '1':

If we run a query using 't1' and 't2' to list pairs of indices in that session, Teneo Query Language tries to fit 't1' and 't2' to all the possible permutations:

By adding a constraint to the query at the end of the query — will return a more meaningful result:

This is just to demonstrate that the identifier used for the transaction is independent from the transaction's actual location in the session. Teneo Query Language simply finds a way to match them in any way possible to the transactions that make up the session.
Event
Each transaction consists of a collection of events that records everything that happened in the solution from the beginning to the end of the transaction. This is the path the user takes from start until they receive a response. These are referred to as events when writing queries in Teneo Query Language.
A transaction holds these three types of events:
- Request - the call to the bot with the user input and all additional parameters
- Path - the path the user input takes through the solution until a response is received.
- Response - the bot's response along with Outputs returned to the user
Properties associated with the set of events include:
- Event properties
- Global Variables
- Flow Variables
- Metadata
- Annotations
- Request Parameters
Let's take a look at what happens in our 'Longberry Baristas' solution when the 'User asks about types of coffee that are available'.
Request event
The request is always the first event in a transaction and includes the main properties associated with the request:

Path event
Next, you find path events, which can add up to quite a large number of data. Everything that happens — every script that runs; every flow that is raised, paused, or dropped; every listener, transition, and node reached — is recorded as an event. The new value of any global or flow variable that is assigned during the event is also recorded as part of the event. Events are listed in the order that they occur.

Let us expand one of the main events and see which properties it contains:

Important properties to query might be the flow's name (fname) associated with the "raise-flow" pathType. Note: since fname may be part of many different events, you may want to combine a query of raised flows with pathType == "raise-flow". You can view some sample queries in TQL Cookbook.
Response event
The last event of a transaction is always the response, which looks something like this:
Referencing event properties
Since events all belong to a transaction, we can reference them in the context of a transaction. So the 'address' of the userInput property could look like this:
t.e.userInput
Just as with transactions, you can choose identifiers to refer to event properties, such as 'e1' and 'e2'. If we refer to two different properties using the same transaction and event identifiers, the two properties must belong to the same transaction and event:
- t1.e1.userInput
- t1.e1.pathType
If we use different identifiers, the two properties is not forced to belong to the same transaction and event.
- t1.e1.userInput
- t1.e2.pathType
You can also apply constraints to specify ordering, transaction, etc:
| Event identifiers | Constraint | Meaning |
|---|---|---|
| t.e1, t.e2 | t.e1.eventIndex != t.e2.eventIndex | 'e1' and 'e2' must be different events in the same transaction |
| t.e1, t.e2 | t.e1.eventIndex == t.e2.eventIndex - 1 | 'e1' and 'e2' must be consecutive events in the same transaction |
| t.e1, t.e2 | t.e1.eventIndex < t.e2.eventIndex | e1 must occur before e2 in the same transaction |
Path types
In the above section we showed you a query looking for a path type of raise-flow. By way of reference, here is the list of path types that are most frequently used in queries. If you'd like to view all the path types occurring in your solution you can try the follwoing query, d t.e.pathType.
| Path type | Meaning |
|---|---|
| flow-trigger | a flow trigger is matched |
| raise-flow | a flow enters the flow stack |
| pause-flow | flow execution is halted/paused |
| continue-flow | flow execution is continued when new input comes in after this flow was paused |
| resume-flow | flow execution is continued after another flow interrupted the execution of this flow |
| drop-flow | a flow is dropped off the flow stack |
| variable-change | a global or flow variables changes value |
| session-script | a global script is executed |
| script | a flow script node is executed |
| flow-script | a flow script (on-top or on-drop) is executed |
| input-processor-results | results of all processors acting in the current input |
| flow-node | a flow link node was executed |
| output | an output node was executed |
| listener | a listener condition was matched and the listener was executed |
| transition | a transition was traversed |