RAQL base combinators

The RAQL base combinators include:

  • empty()

  • galaxy(galaxy-name)

  • combine(<op>, <query-1>, <query-2>)

  • project(([<name>, <expr>])*, <sub-query>)

  • restrict(<filter-exp>, <query>)

  • order(([<direction>, <expr>],)+ <sub-query>)

  • groupingProject(([<name>, <expr>])*, <sub-query>)

  • distinct(<sub-query>)

  • textSearch(<fulltextExpr>, ([<direction>, <expr>],)*, <sub-query>)

Empty combinator contains one empty tuple (it is related to the DUAL table in databases). This relation is helpful when a query is used to compute the value of expression rather than selecting information from the database. The following example returns one tuple containing the value 4711:

 

project(["value", const(4711)],

        empty())

 

A galaxy is a built-in relation that makes entities from Integration Service available to the query language. For an overview of available galaxies see Addressable entities and operators in RAQL.

So called transient galaxies contain values only during the execution of a specific operation. When referenced at any other time, these galaxies are empty. The main application for such galaxies is to specify the rights for certain operations such as the creation of new documents. They cannot be used during searches because at this point they are empty.

The galaxy to use is passed as an argument to galaxy:

galaxy(galaxy-name)

The following example query would return a list of all revision ids (the built-in operator revisionId accepts a value of type revision and returns the revision’s id):

 

project(["revId", ima:revision:revId(ref("revisions"))],

        galaxy(revisions))

 

The resulting scheme consists of tuples which all have one component of type UUID with the label revId.

The combine combinator may be used for one of the following set operations as parameter <OP>:

  • union

  • intersection

  • difference

  • product

Syntax: combine(<op>, <query-1>, <query-2>)

Here is an example for a set union:

 

combine(union,

      restrict(ima:attribute:hasValue(

                  ima:metadata:color(ref("revisions")),

                  const("green")),

                galaxy(revisions)),

       restrict(ima:attribute:hasValue(

                  ima:metadata:color(ref("revisions")),

                  const("blue")),

                galaxy(revisions)))

 

A projection modifies the scheme of a query. It may be used to achieve a variety of effects.

Syntax: project(([<name>,<expr>])*,<sub-query>)

Consider the following example:

project(["revId", ima:revision:revId(ref("revisions")),

        ["isLatestRev", ima:revision:isLatest(ref("revisions"))],

        galaxy(revisions))

This query takes the sub-query galaxy(revisions) and projects it into a query with the following scheme:

Each tuple has two elements, one named revId (type string) which contains the revision ID and one named islatestRev (type Boolean) which indicates whether the revision with this ID is the latest revision of the corresponding document.

A restriction filters out all tuples that match a given expression.

Syntax: restrict(<filter-exp>, <query>)

Filter-exp is an expression with type Boolean and query is an arbitrary query. The following example query selects all latest revisions and returns their revision ids:

 

project(["revId", ima:revision:revId(ref("revisions"))],

        restrict(ima:revision:isLatest(ref("revisions")),

                 galaxy(revisions))

 

The restrict combinator calls the operator ima:revision:isLatest which accepts a value of type revision and returns a Boolean indicating whether the revision is marked as being the latest of a document. The scheme of the query contains one component of type string and has the label revId.

The order combinator changes the order of the tuples and therefore allows sorting the results of a query.

Syntax: order(([<direction>, <expr>],)+ <sub-query>)

The combinator constructs a query with the same scheme and contents as sub-query, but the result is sorted by the values of the expressions and the directions specified. There must be at least one sorting expression. Sorting expressions are arbitrary expressions. The type of the value returned, however, must be suitable for sorting (see below). If more than one sorting expression is given, the results of sub-query will be sorted by all criteria. The left-most expression is the sorting criteria with the highest priority. The expressions must be of a sortable type (string, number, date or time).

The following example query returns all revisions and sorts them ascending by their creation time:

 

order([asc, ima:revision:creationTime(ref("revisions"))],

      galaxy(revisions))

 

The groupingProject combinator accumulates the results of a query into one (or more) results using aggregation expressions. In contrast to project, associations in a groupingProject query may contain aggregation expressions. Associations that do not contain an aggregation operator are used to group the result and thereby produce multiple results. The scoping semantics of project and groupingProject are the same. The scheme of a groupingProject query is given by its associations.

Consider the following example:

 

groupingProject(["docCount", aggregation(count, ref("revisions"))],

                restrict(ima:revision:isLatest(ref("revisions")),

                         galaxy(revisions)))

 

The distinct combinator eliminates duplicate tuples from the result of a query.

Syntax: distinct(<sub-query>)

The combinator constructs a query with the same scheme and components as sub-query, but with no duplicate tuples. To achieve this, the combinator may change the order of the resulting tuples.

The textSearch combinator filters and optionally orders tuples containing revisions using the full-text search engine.

Syntax: textSearch(<fulltextExpr>, ([<direction>, <expr>],)*, <sub-query>)

The textSearch combinator is different from the other combinator and may not be freely mixed with the other combinators. It may only be used the with the following conditions:

Using textSearch() without a configured full-text engine in the system is an error.

textSearch() may only be the outermost query element. It may not be surrounded by further combinators.

The <sub-query> must have a scheme with only one component of the type revision.

Both expressions in <fulltextExpr> and optional order specifications must be translatable into a full-text requests. Use of any operator or expression that cannot be translated causes an error.

Any order combinator within <sub-query> has no effect on the order of the result types. Sorting must be performed using order specifications in the textSearch combinator itself.

The full-text engine only indexes the latest revision of each document. Therefore, the textSearch() combinator cannot be used to search for old revisions.

The following example finds all revisions containing the word “example”:

 

textSearch(

  ima:revision:contains(ref("revisions"), const("example")),

  galaxy(revisions))

 

Using full-text search operators in constant literals

Any constant literal containing search terms is passed to the full-text engine, which interprets certain characters or keywords in a specific manner. Typically, search operators such as “AND”, “OR” and “NOT” (spelled with capital letters) or the asterisk “*” as wildcard character are supported. The exact behavior depends on the customization of the full-text engine, for example concerning stop words or language dependent word stemming. In any case the search behavior is the same as if the full-text search is conducted from the ImageMaster WorkplaceClient. For further details also see the section “Text Search Features” in the WorplaceClient user manual [UM WorkplaceClient], which provides an overview of search features that are supported in a standard full-text environment.

Resulting from the above, there are alternative means for expressing a full-text query by using full-text search expressions in the constant literal of a full-text search. For instance, in a full-text query the common RAQL operators can be used to search for revisions containig the keyword “ImageMaster” or “Telekom”:

<query language="RAQL">

textSearch(

  or(

    ima:revision:contains(ref("revisions"),const("ImageMaster")),

    ima:revision:contains(ref("revisions"),const("Telekom"))),galaxy(revisions))

</query>

 

Alternatively, the logical operators (AND, OR, and NOT) can be used within the constant literal to get the same search result:

<query language="RAQL">

textSearch(

  ima:revision:contains(ref("revisions"),

  const("ImageMaster OR Telekom")),

  galaxy(revisions))

</query>

Within the full-text search literal (“ImageMater OR Telekom” in the example above) brackets are not supported and the OR operator has a stronger binding than the AND operator when being used in the constant literal expression! Therefore, you cannot convert the below example statement, which combines a RAQL “OR” operator with a full-text “AND” operator into an expression which uses both (OR as well as AND) within the full-text search literal only:

<query language="RAQL">

textSearch(

  or(

    ima:revision:contains

     (ref("revisions"),const("ImageMaster AND TSystems")),        

    ima:revision:contains(

      ref("revisions"),const("Telekom"))

     ),

  galaxy(revisions))

</query>

 

In general, the wildcard character “*” can also be used within the constant literal and the logical operators are also interpreted in all four base languages that are supported by ImageMaster (English, German, Spanish, and French). For example, the German expression “ODER” would be interpreted in the same manner as “OR” when being used in the constant literal of a full-text search (but it cannot be used as RAQL operator):

<query language="RAQL">

textSearch(

  ima:revision:contains

    (ref("revisions"), const("ImageMaster ODER Telekom")),

  galaxy(revisions))

</query>