Queries with MxL

The following exemplary expressions show how MxL can be used to access and query the SocioCortex data model. For this purpose, we use a data model with Deparments, Employees, and Projects as a foundation:

Overview over basic types of MxL

Based on this data model, we can formulate the following queries:

Exemple Query Type of Result Description
find(Employee) Sequence<Employee> Returns all instances of entity type Employee. The built-in-keyword find expects an entity type as input and returns a sequence of all instances of the given entity type. Assuming T is an arbitrary entity type, find(T) would return an object of type Sequence<T>.
find(Employee)
.where(e => e.Salary > 20)
Sequence<Employee> Returns all employees, whose salary is greater than 20.
find(Employee)
.where(Salary > 20)
Sequence<Employee> Again, returns all employees, whose salary is greater than 20. However, this time we use an implicit lambda as parameter instead of an explicit one.
find(Employee)
.where(Salary > 20)
.select(Name)
Sequence<String> Returns the names of all employees, whose salary is greater than 20.
find(Project)
.select({
Name: Name,
Count: Member.count()
})
Sequence<
Structure<
Name: String,
Count: Number>>
Determines the count of employees working on each project.
find(Project)
.select({
Name,
Count: Member.count()
})
Sequence<
Structure<
Name: String,
Count: Number>>
Again, determines the count of employees working on each project. However, for the Name-property, we use a shorten syntax.
find(Project)
.select({
Name: Name,
Count:
Member.select(Location)
.distict().count()
})
Sequence<
Structure<
Name: String,
Count: Number>>
Determines the count of departments for each project.
find(Department)
.where(d => d.get Employee whereis Location
.any(e => e.Salary > 20 ))
Sequence<Department> Returns all departments, in which there is at least one employee with a salary greater than 20. The get T whereis <relation>-construct is a mechanism to navigate reversely through the data model. In Tricia, this construct will always return an object of type Sequence, since there is no possiblity to define reverse multiplicities (e.g. we cannot define that there has to be at least one Employee in a department).
find(Department)
.where(get Employee whereis Location
.any(Salary > 20 ))
Sequence<Department> Again, returns all departments, in which there is at least one employee with a salary greater than 20. However, this time we use an implicit lambda, while the get T whereis <relation>-construct also uses the implicit lambda-parameter.
find(Department)
.sum(get Employee whereis Location
.count())
Number Calculates the sum of employees in all departments.
/* First we define a function,
which determines if a given employee
has at least one project */

let hasWork = (e:Employee) =>
e.get Project whereis Member
.isNotEmpty() in

find(Department)
.ratio(get Employee whereis Location
.all(e => hasWork(e)))
Number Calculates the ratio of departments, in which each employee has at least one project he works on. Sometimes, for the sake of clarity, it may be advisable to add meaningful comments on the one hand, and to define certain sub expressions like functions or predicates separately on the other hand.