Building Search Queries
When assembling a search action, a Query element is needed to describe the items to retrieve from the database.
Structure of a Query
A complete query is described by a Query
element from the common schema.
The contents of the Query
element is sequence of one or more AbstractQuery elements which are connected by an implicit Or disjunction. The overall structure is described by the following recursive grammar:
TopQueryType ::= Query{AbstractQuery+}
AbstractQuery ::= AbstractSimpleQuery | AbstractDecoratedQuery | CompoundQuery
CompoundQuery ::= Or{AbstractQuery+} | And{AbstractQuery+} | Not{AbstractQuery}
AbstractDecoratedQuery ::= Require{AbstractSimpleQuery} | Exclude{AbstractSimpleQuery}
AbstractSimpleQuery ::= Id | Any | LastUpdate | AbstractDefinedFieldsQuery
Simple Queries
Simple queries express search criteria on a single field of the queried entities.
Simple Query |
Type |
Item Field |
---|---|---|
|
the item identifier |
|
|
the virtual default search field |
|
|
the last updated timestamp |
|
AbstractDefinedFieldsQuery |
consult defining schema |
extension point for additional search criteria |
For the specification of the various additional search criteria, consult the XSD schema of the respective concrete search request.
Simple Query Decorators
Decorators wrap a single simple query to refine the semantics of the wrapped search criteria.
Decorator |
Semantics |
---|---|
|
The wrapped simple query must match |
|
The wrapped simple query must not match |
Compound Queries
Compound queries compose their nested child element queries.
Compound Query |
Semantics |
---|---|
|
Disjunction: Any child element query (clauses) must match |
|
Conjunction: All child element queries (clauses) must match |
|
Negation: The single child element must not match |
Simple Query Types
String Queries
String queries are used for querying text based data.
Example: Searching for the phrase ‘blue light’
<Any>blue light</Any>
Example: Searching for the words ‘blue’ or light’
<Or>
<Any>blue</Any>
<Any>light</Any>
</Or>
Example: Disabling the wildcard semantics of *
by setting the escape="true"
attribute.
<Any escape="true">three stars ***</Any>
Important
Make sure that your XML is well‑formed by correctly escaping all special characters.
When constructing the ApiRequest
XML with string templating mechanisms,
the following characters must be replaced by their respective XML entities:
<
must be replaced with<
>
must be replaced with>
&
must be replaced with&
'
(apostrophe) must be replaced with'
"
(quotation mark) must be replaced with"
Escaping Utilities:
Java:
org.apache.commons.lang3.StringEscapeUtils.escapeXml10("Pam & Sam say, \"I'm impressed by the <Data>!\"")
Python:
import xml.sax.saxutils as saxutils; saxutils.escape('''Pam & Sam say, "I'm impressed by the <Data>!"''')
PowerShell:
[System.Security.SecurityElement]::Escape("Pam & Sam say, ""I'm impressed by the <Data>!""")
These functions will yield the following escaped string:
"Pam & Sam say, "I'm impressed by the <Data>!""
DateRange Queries
DateRange queries are used for querying data based on date and time.
Query attribute |
Default |
Description |
---|---|---|
|
|
If true the lower bound is included (“greater than or equal”) |
|
|
Lower bound of the range (“start”). |
|
|
Upper bound of the range (“end”). |
|
|
If true the upper bound is included (“less than or equal”) |
Note
If present, the bounds will always be completed to full xs:dateTime
timestamps including timezone information, to denote a precise point in time.
If the timezone information is not specified, it will be set to Europe/Zurich
.
If the abbreviated xs:date
format is used, then the missing time will be set to
midnight in Bern, Switzerland (i.e., 00:00:00
in the Europe/Zurich
timezone).
Note
In the underlying database, all date and time information is stored as a single numerical value representing the milliseconds since the “epoch”, which is January 1, 1970, 00:00:00 UTC.
Therefore, when querying, the from
and to
values that define the range of included data must be mapped to the same numerical timeline.
For representing date-only information, the time component is set to midnight in Bern, Switzerland (i.e., 00:00:00
in the Europe/Zurich
timezone).
For example, February 1, 2025 (2025-02-01
) is actually represented as 2025-02-01T00:00:00+01:00[Europe/Zurich]
,
which corresponds to 2025-01-31T23:00:00Z
in UTC time and equals to 1738364400000
milliseconds since the “epoch”.
Note
When using the default inclusive lower limit and exclusive upper limit behavior, i.e., includeFrom="true"
and includeTo="false"
,
we adhere to the well-established tradition of using half-open intervals in computer science and many mathematical domains (set theory, calculus, analysis, etc.).
A major benefit of this convention is that it ensures clear demarcation between intervals without overlap when performing covering traversals of the timeline in multiple queries.
For example, if you have one interval [a, b)
and the next [b, c)
, the point b
is clearly part of the second interval, not the first.
This eliminates ambiguity and ensures that each point in time is covered exactly once, thus preventing missing or duplicate results.
Example: Last updated in February 2024. Note how this pattern correctly selects an entire month, regardless of whether it has 28, 29, 30, or 31 days.
<LastUpdate from="2024-02-01" to="2024-03-01" />