Contents |
[edit] Bongo Query Language
A number of store commands can be supplemented with simple queries, which clients can use to get back more specific information than the standard commands and parameters allow.
[edit] Why a query language?
It's relatively clear that a number of clients will need or desire data sets which are more specific than our standard commands can return, so this simple query language was put in place. It is also used internally, so many of the commands which seem to do equivalent things are actually translated "under the hood" as it were.
By enabling this flexibility, the store can become a much richer source of information, and reduce the burden on client applications.
[edit] Overview
The query language has been designed to be parsed extremely efficiently, and is set-up so that it can be translated readily into SQL commands. As a consequence of this, it is rather less human-friendly than the rest of our protocol, but while it looks strange on the surface, it is extremely easy to use once you understand it.
The language is formed of operators and functions, all of which take two arguments, and the notation is infix: the operator or function name comes first, followed by the two arguments.
The operators are:
| Operator | Description |
|---|---|
| & | Logical AND |
| | | Logical OR |
| = | Equivalency / equality |
| ! | Inequivalence / inequality |
| < | Less than (numeric expressions) |
| > | Greater than (numeric expressions) |
| ~ | Bitfield AND |
The functions are:
| Function | Description |
|---|---|
| { | Left-substring of, taking a length and property name argument |
| } | Right-substring of, taking a length and property argument (to be implemented) |
| l | Document Linked to/from, taking a direction (to/from) and a document guid |
Expressions are of the form:
[operator] [sub-expression] [sub-expression] [function] [constant] [constant]
A constant could be an integer, a string, or a document property name (for example, nmap.guid being the guid of the document).
These tokens are parsed thusly:
| Token | Format | Regex |
|---|---|---|
| Operator / Function | All operators/functions are single non-numeric characters | ^[^0-9]$ |
| Number | Numbers are one or more digits | ^[0-9]+$ |
| String | Strings are quoted, and contained quotes are \-escaped | ^".*"$ (escaping not represented) |
| Property name | Properties are lower-case alpha-numeric, and may contain periods | ^[a-z][a-z0-9]+(?:\.[a-z][a-z0-9]+)*$ |
Because of these definitions, all tokens are unambiguous: they fall into none or exactly one of the above categories.
[edit] Examples
In order to understand these examples, you may need to know a little bit about our store protocol already, and how the store operates.
The context of these examples is a request to the store, for example via MESSAGES, and we are using the query to refine the documents returned to only those we are interested in.
[edit] Mail documents from Jim
Mail documents have the store type 0x2, and Jim's address is 'jim@example.com', which will be stored in the 'bongo.from' property of any e-mail.
The logic for this query is "(nmap.type = 2) AND (bongo.from = 'jim@example.com')".
In BQL, this becomes:
& = nmap.type 2 = bongo.from "jim@example.com"
