Selecting data
The types used in these queries are defined here.
Select a Movie with associated actors and reviews with their authors:
select Movie {id,title,year,description,actors: {id,full_name,},reviews := .<movie[is Review] {id,body,rating,author: {id,name,}},}filter .id = <uuid>'09c34154-4148-11ea-9c68-5375ca908326'
Select movies with Keanu Reeves:
select Movie {id,title,year,description,}filter .actors.full_name = 'Keanu Reeves'
Select all actors that share the last name with other actors and include the same-last-name actor list as well:
select Person {id,full_name,same_last_name := (withP := detached Personselect P {id,full_name,}filter# same last nameP.last_name = Person.last_nameand# not the same personP != Person),}filter exists .same_last_name
The same query can be refactored moving the with block to the top-level:
with# don't need detached at top-levelP := Personselect Person {id,full_name,same_last_name := (select P {id,full_name,}filter# same last nameP.last_name = Person.last_nameand# not the same personP != Person),}filter exists .same_last_name
Select user names and the number of reviews they have:
select (User.name,count(User.<author[is Review]))
For every user and movie combination, select whether the user has reviewed the movie (beware, in practice this maybe a very large result):
select (User.name,Movie.title,Movie in User.<author[is Review].movie)
Perform a set intersection of all actors with all directors:
with# get the set of actors and set of directorsActor := Movie.actors,Director := Movie.director,# set intersection is done via the filter clauseselect Actor filter Actor in Director;
To order a set of scalars first assign the set to a variable and use the variable in the order by clause.
select numbers := {3, 1, 2} order by numbers;# alternativelywith numbers := {3, 1, 2}select numbers order by numbers;
Selecting free objects.
It is also possible to package data into a free object. Free objects are meant to be transient and used either to more efficiently store some intermediate results in a query or for re-shaping the output. The advantage of using free objects over tuples is that it is easier to package data that potentially contains empty sets as links or properties of the free object. The underlying type of a free object is std::FreeObject.
Consider the following query:
with U := (select User filter .name like '%user%')select {matches := U {name},total := count(U),total_users := count(User),};
The matches are potentially {}, yet the query will always return a single free object with results, total, and total_users. To achieve the same using a named tuple, the query would have to be modified like this:
with U := (select User filter .name like '%user%')select (matches := array_agg(U {name}),total := count(U),total_users := count(User),);
Without the array_agg() the above query would return {} instead of the named tuple if no matches are found.
︙
See also |