StringQuery Format

The StringQuery consists is a user-friendly syntax for providing search conditions. Note that input is accepted in any local including none latin characters.

Tip

Whitespace characters (including new lines) are ignored for better readability.

field-name: value1, value2; and field-name:value1,value2; Are technically the same.

But spaces within a value like field: hello world are prohibited. You must quote the entire value then: field: "hello world"

New lines in a value are always prohibited.

The syntax consists for field-values pairs. Values are separated using a single coma (,). And pairs are separated using a single semi-colon (;)

username: value1, value2;

username is the field-name, value1 and value are the values of the username field.

The ; character at the end of the query-pair indicates that the values list has ended, and a new pair or subgroup can be started.

Tip

When the pair is last in the group or at the end of the input it can be omitted.

field1: value1, value2; field2: value1, value2;

Can shorted to.

field1: value1, value2; field2: value1, value2

Field-name

A field-name is limited in formatting, it must start with an alphabetic character or word from any language. So a to z or “价” (price) in Simplified Chinese.

After this it may be followed be a number, alphabetic character, word or a dash - or underscore _ any given number of times.

The following fields-names are valid:

  • price
  • price0
  • total_price
  • total-price

The following field-names are invalid:

  • 0K (must not start with a number)
  • 0价 (must not start with a number)
  • 0 (must not start with a number)
  • _price (must not start with an underscore)
  • -price (must not start with an dash)
  • total-price: (must not end with an double colon :).

Values

A value can be anything from a word, a sentence, number or specially formatted value like a date. But not all values can be used directly.

Note

If the value contains special characters (including spaces) the value must be quoted using double quotes (").

Special characters are: [<>[](),;~!*?=&*, otherwise these characters could be interpreted as value/field separate or give a syntax error.

If the value itself contains double quotes these must be escaped by duplicating theme, so va"lue becomes va""lue and va""lue becomes va""""lue.

Escaped quotes will then be normalized when processing the input.

Caution

Be careful with quotes at the beginning, ""foo" might seem valid, but the first quote is used to indicate a quoted value.

The correct usage is """foo" which is transformed to "foo

Using a value like described above is whats called a “simple value”. If there are more we call them of a list of simple values.

But as simple values alone are not really useful, you can also use excluded simple values, (excluded) ranges, comparisons, and pattern matchers.

To mark a value as being excluded prefix it with an exclamation (!), this works for almost all value types except comparisons and pattern matcher which have there own syntax.

field: !value, !1 ~ 10;

As some values are part of an expression like a range, the value is referred to as a value-part.

Ranges

A range consists of two sides, a lower and upper bound (inclusive by default). Each side is considered a value-part and must follow the value convention (as described above).

The following condition is seen as: field1 is between (inclusive) 1 and 100, and field2 is between (inclusive) -1 and 100.

field: 1-100; field2: -1 ~ 100

Each side is inclusive by default, meaning the ‘value’ itself and anything lower/higher then it. To mark a value as exclusive (everything between, but not the actual value) use the outer turning square brace ] for the lower-bound and [ for the upper-bound.

  • ]1 ~ 100 is equal to (higher then) 1 and (equal to or lower then) 100)
  • [1 ~ 100 is equal to (equal to or higher then) 1 and (equal to or lower then) 100)
  • [1 ~ 100[ is equal to (equal to or higher then) 1 and (lower then) 100)
  • ]1 ~ 100[ is equal to (higher then) 1 and (lower then) 100)

You can also mark a bound explicitly inclusive using [ for lower-bound and ] for the upper-bound to mark the. But as bounds are inclusive by default you don’t have to do this, it’s merely for explicitness.

Comparison

Comparisons are pretty straightforward, each comparison starts with an operator followed by a value-part.

Supported operators are:

  • < (lower then)
  • <= (lower then or equal to)
  • <> (not higher or lower then (same as marking the value as excluded))
  • > (higher then)
  • >= (higher then or equal to)
field: >=1, < -10, date: > 06/02/2015

Tip

Whenever possible try to use ranges instead of multiple comparisons, because ranges can be optimized.

PatternMatch

PatternMatchers work similar to Comparisons, everything starting with a tilde (~) is considered a pattern-matcher.

Supported operators are:

  • ~* (contains)
  • ~> (starts with)
  • ~< (ends with)
  • ~= (equals)

And not the excluding equivalent.

  • ~!* (does not contain)
  • ~!> (does not start with)
  • ~!< (does not end with)
  • ~!= (equals)
field: ~> foo, ~*"bar";

To mark the pattern case-insensitive add an ‘i’ directly after the ‘~’.

field: ~i> foo, ~i!* "bar";

Subgroups

For more complex conditions you can nest pairs inside subgroups. Subgroups are separated the same way as pairs, using the ; character.

And just like field-values pairs, the group separation character can be omitted when the group is last in the group or input.

(field-name: value1, value2;); (field-name: value1, value2)

Or in combination with field-values pairs.

field-name: value1, value2; (field-name: value1, value2)

Tip

Noticed that pair in the second subgroup does not end with a ;?

That’s because the processor is smart enough to know that the group has ended here and it can simply ignore the missing ; and continue. If there was a second pair or nested subgroup an ; is required.

By default all groups are marked as logical AND, meaning all the fields within the group must give a positive match. For explicitness you can use this to mark the group as logical AND.

&(field1: values; field2: values);

To change a group and make it OR’ed (at least one field must give a positive match), prefix the group with a star * character.

*(field1: values; field2: values);

If you want to head-group (the condition itself) OR’ed or AND (default) use * or & as the first character in the condition.

* field1: values; field2: values;
&field1: values; field2: values;

Caution

The OR’ed symbol works only on groups, because the condition always starts with a group the OR’ed symbol is only valid at the start of a condition or subgroup.

So the following is invalid: is_admin: t; * enabled: f;

But this is valid: is_admin: t; *(enabled: f) and marks subgroup 0 as OR’ed.