To get started using Quaere, let's begin with a simple Java program.
Quaere has not yet been released and some of features are likely to change. At the time of writing, no binary distributions have been released. To start using Quaere today, please can follow the steps described here.
Creating the project
Quaere is a query language
The Quaere query language is an internal DSL written in Java. To achieve rich language integration without the need for preprocessors, code generators or similar, Quaere employs some unconventional programming techniques. Luckily, this is tucked away inside of the Quaere API and there is only one thing you'll have to do to bring the querying abilities of Quaere to your own applications - use a static import to get the language in place.
Writing our first queries
Once we have the
import statement in place, we're ready to write our first query. For this introduction we'll only be using the Quaere for Objects querying engine. Keep in mind that Quaere is a query language and that these queries would look exactly the same if other data sources, such as a JPA EntityManager, where queried.
When we run this program, it will print:
As you can see, the Quaere query language resembles SQL, the difference is that it queries are written "backwards" - starting with the from clause and ending with a select clause. The primary reason for this is that in a Quaere query, data flows in order of the clauses. In the query above we start with defining an city alias for the cities array and then select each city into a new collection called allCities.
Let's move on to writing a query that restricts the results using a where-clause.
When we run this program, the populations for London, New York and Tokyo will be printed. If you're familiar with Hibernate's Criteria API, you should recognize the gt operator. Quaere uses this shorthand form for greater than comparisons. The expression in the previous sample is analogous to
population > 10000000.
Our code suffers from primitive obsession, so it's time to introduce a City domain object.
Now, let's change our query so that we select the names of the large cities.
When we run this program, it will print the names London, New York and Tokyo. Let's dive into what this query does. Similar to our first example, we first define an alias for the elements in the cities array, then we define a restriction predicate that says that only the cities whose population is greater than ten million should be included in the result. Notice that we refer to the getter (
getPopulation()) of the
City class in our predicate. Finally we select the names of the cities who matched the predicate.
Now you've learned the basics of Quaere. Let's move on to using some more features.
Unleashing the power of Quaere
Quaere supports most of the operations you're familiar with from SQL. In this section we'll learn how to use these to write more advanced queries.
Just like with SQL, you can order the results of your queries using an order-by clause. A Quaere query results in a sequence of elements that are produced in some order that is intrinsic in the underlying information sources. Just like SQL, Quaere has operators for controlling the order of the query result. The most basic of these operators is the
Let's order the cities by their population...
When we run this example, the cities will be ordered by their population in ascending order.
Naturally, we can also sort the cities in descending order. To do this, simple change the
orderBy keyword to
We can also combine different ordering clauses. The example below sorts the cities by their names in ascending order and then by their population in descending order.
Quaere also includes a groupBy operator which imposes a partitioning over a sequence of elements based on a key extraction function. The groupBy operator creates a
Group element for each distinct key that was encountered. Each
Group contains the key and the group of elements that mapped to the key.
Let's group our list of cities by continent...
When we run our program, we'll get this output:
Notice that the query produces a sequence of
Group instances rather than
City instances. The
Group class is a special purpose class used to demote groups.