The Tree/Triple Query Language or TQL is designed for searching graphs or trees of data such as stored JSON. SPARQL is another alternative but it is designed with just triples and it becomes complex quickly when trying retreive something as simple as a JSON document with a matching nested ID element. With that in mind, TQL attempts to be simple yet powerful query language focussed on tree or JSON based operations.
TQL can be represented in two formats, a friendly SQL like format and a JSON encoding of the same concepts expressed in the friendly format. The JSON encoding is a marshalling of the friendly format as described on the JSON TQL page.
A JSON document can be decomposed into triples where a triple is a Subject/Predicate/Object. The Subject and Object parts are referred to as nodes. To store JSON object in a triple store such as OpO a node is used for the JSON object which can be thought of as being the opening curly brace. For each member of the JSON object there is a Predicate matching the member key and an a node for the member value. The triple that represents the JSON object member relationship has a reference number. This number is not exposed in the TQL interface.
A JSON array mapping to nodes and predicates is less obvious and clear cut. For OpO a node is used to represent the array. Each member of the array is also a node. A special empty or nil predicate is used to form the triple that is stored in OpO. To preserve the order of the array members additional information is stored in the triple or rather the triple's reference number.
JSON document are generally more complex than an object with one member. Putting the pieces together to form a tree chains nodes together with predicates. With many JSON objects stored in OpO as triples it is useful to be able to identify the root a JSON object. Every node has a reference number. This number can be used to SELECT a JSON object if the WHERE caluse indicates that reference number. The node reference number can also be used with the DELETE, SELECT, and UPDATE operations.
Like most database servers, OpO supports paritioning of the data store into multiple databases. Each of the operations support the USE keyword which identifies one or more databases to use in a query. If the USE keyword is not used then the 'default' database is used.
Operation make use of conditional expressons is the WHERE and FILTER values. These expressions use a path or TPath to identify elements in a tree or JSON Objects and and Arrays. TPath describes a path from a node to another node using predicates as steps in the path. TPath is a subset of JsonPath as it is used in a more focussed way. WHERE clause evaluation traverses from the leaf to the root of a tree. The TQL functions are used to identify leaf nodes and then an attempt is made to follow the path in reverse to build up a matching set of nodes.
As an example, conceptually x.y would walk from the root down the x predicate to a node and then on the y predicate to the destination node. In practive, a matching node is found first and the predicate y followed back to node and then the x leg is taken back to a candidate node.
A path that traverses an array can not use a predicate to describe the next node in the path. Instead, for arrays, numeric path steps are used. A TPath of x.1 describes the path through the x predicate and then on to the second element of the array. The index is zero based giving the first element an index of zero.
There are a few special TPath elements. The $ element represents the root of a tree. An empty element .. matches any number of predicate legs. A wild card element, * matches exactly one predicate that can be anything.
OpO supports more types than allowed in JSON. These have JSON mappings in returned JSON and also in TQL encoded as JSON. Depending on configuration options inserted or updated JSON value will be converted to the OpO type based on value patterns. JSON Objects and Array are also supported.
The friendly TQL syntax is similar to SQL. Keywords such as SELECT and WHERE are followed by a value. If multiple statements are included in a stream of file they must be separated by two blank lines. Comments begin with a # character. All keywords are case insensitive.
The JSON encoding for a TQL statement is a JSON Object with each clause a member of the Object. The expressions in the WHERE and FILTER are converted to nested JSON Arrays where the operation become the first element of the Array and the remaining arguments become the rest of the Array members. Additional rules apply to the different value types. Those are discussed on the WHERE page.