Edit on Github

Match Clause

We use match clauses to retrieve data instances and schema types that follow a particular pattern. Using match clauses forms the basis of our data retrieval. By defining the schema, we effectively define a vocabulary to be used to describe concepts of our domain.

Once the schema is defined, we can form graph patterns for which we want to search within our knowledge graph. We do that by using match clauses. Each match clause represents a particular graph pattern via its corresponding query pattern. The match clause is then executed as a part of a Get, Insert, Delete or Aggregate query. In the case of a Get query, what we expect to be returned is the tuples of instances fulfilling the specified pattern.

In the subsequent sections, we shall see how to match specific graph patterns. To try the following examples with one of the Grakn clients, follows these Clients Guide.

Match Instances of Concept Types

What follows in this section, describes how we can use the match keyword to find instances of data that we are interested in. What we choose to do with the matched result, is out of the scope of this section. But for the sake of completeness, we end each match clause with get;. In the next section, we learn about using get for the retrieval of information from the knowledge graph.

Match instances of an entity

Matching instances of an entity type is easy. We do so by using a variable followed by the isa keyword and the label of the entity type.

[tab:Graql] ```graql match $p isa person; get $p; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("p").isa("person") ).get("p"); ``` [tab:end]

The example above, for every person, assigns the person (entity) instance to the variable $p.

Instances of an entity with particular attributes

To only match the instances of entities that own a specific attribute, we use the has keyword, followed by the attribute’s label and a variable.

[tab:Graql] ```graql match $p isa person, has full-name $n; get $p; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("p").isa("person").has("full-name", var("n")) ).get("p"); ``` [tab:end]

We soon learn how to target attributes of a specific value.

Match instances of a relation

Because of the dependent nature of relations, matching them is slightly different to matching entities and attributes.

[tab:Graql] ```graql match $emp (employer: $x, employee: $y) isa employment; get $emp; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("emp").rel("employer", "x").rel("employee", "y").isa("employment") ).get("emp"); ``` [tab:end]

The example above, for every employment, assigns the instance of the employment (relation) type to the variable $emp, the instance of the employer organisation (entity) type to the variable $x and the instance of the employee person (entity) type to the variable $y.

Instances of a relation with particular attributes

To only match the instances of relations that own a specific attribute, we use the has keyword followed by the attribute’s label and a variable.

[tab:Graql] ```graql match $emp (employer: $x, employee: $y) isa employment, has reference-id $ref; get $emp; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("emp").rel("employer", "x").rel("employee", "y").has("reference-id", var("ref")).isa("employment") ).get("emp"); ``` [tab:end]

We soon learn how to target attributes of a specific value.

Leave the relation instance unassigned

Assigning a relation to a variable is optional. We may only be interested in the role players of a certain relation. In such a case, we would write the above match clause like so:

[tab:Graql] ```graql match (employer: $x, employee: $y) isa employment; ``` [tab:end] [tab:Java] ```java // FIXME(vmax): anonymous variables are not allowed //GraqlMatch.Filtered query = Graql.match( // var().isa("employment").rel("employer", "x").rel("employee", "y") //).get(); ``` [tab:end]

Leave the roles out

We can always choose to not include the label of roles when matching a relation. This, especially, makes sense when matching a relation that relates to only one role.

[tab:Graql] ```graql match $fr ($x, $y) isa friendship; get $fr; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("fr").rel("x").rel("y").isa("friendship") ).get("fr"); ``` [tab:end]

Match instances of an attribute

We can match instances of attribute types in various ways depending on our use case.

Independent of label

We can match instances of attributes type based on their value regardless of their label.

[tab:Graql] ```graql match $x "like"; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("x").eq("like") ).get("x"); ``` [tab:end]

This matches instances of any attribute type whose value is "like" and assigns each to variable $x.

Independent of owner

We can match instances of attributes based on their value regardless of what concept type they belong to.

[tab:Graql] ```graql match $n isa nickname; $n "Mitzi"; get $n; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("x").eq("Mitzi").isa("nickname") ).get("x"); ``` [tab:end]

This matches instances of the attribute with the label of nickname and value of "Mitzi", regardless of what owns the attribute nickname.

With a given subset

To match all instances of attribute types that contain a substring, we use the contains keyword.

[tab:Graql] ```graql match $phone-number contains "+44"; get $phone-number; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("phone-number").contains("+44") ).get("phone-number"); ``` [tab:end]

This matches instances of any attribute type whose value contains the substring "+44".

With a given regex

The value of an attribute can also be matched using a regex. We allow the range of Java Regex Patterns.

[tab:Graql] ```graql match $x like "(Miriam Morton|Solomon Tran)"; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("phone-number").regex("(Miriam Morton|Solomon Tran)") ).get("phone-number"); ``` [tab:end]

This matches the instances of any attribute type whose value matches the given regex - "Miriam Morton" or "Solomon Tran".

Owners with multiple attributes

To match instances of a concept type that owns multiple attributes, we can simply chain triples of has, label and variable. Separating each triple with a comma is optional.

[tab:Graql] ```graql match $p isa person, has nickname $nn, has full-name $fn; get $p; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("p").isa("person").has("nickname", var("nn")).has("full-name", var("fn")) ).get("p"); ``` [tab:end]

Owners with attributes of given values

We can also match instances that own an attribute with a specific value or range of values.

[tab:Graql] ```graql match $s isa school, has ranking < 100; get $s; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("s").isa("school").has("ranking", Graql.lt(100)) ).get("s"); ``` [tab:end]

But if in this example, we still want to know the ranking of each matched school? we split the variable assignment and the condition like so.

[tab:Graql] ```graql match $s isa school, has ranking $r; $r < 100; get $s; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("s").isa("school").has("ranking", var("r")), var("r").lt(100) ).get("s"); ``` [tab:end]

Disjunction of patterns

By default, a collection of patterns in a match clause constructs conjunction of patterns. To include patterns in the form of a disjunction, we need to wrap each pattern in {} and place the or keyword in between them.

[tab:Graql] ```graql match $p isa person, has full-name $fn; { $fn contains "Miriam"; } or { $fn contains "Solomon"; }; get $p; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("p").isa("person").has("full-name", var("fn")), or( var("fn").contains("Miriam"), var("fn").contains("Solomon") ) ).get("p"); ``` [tab:end]

Instances of a direct type

The type that an instance belongs to may be a subtype of another. This means when we use isa, we are matching all direct and indirect instances of the given type. To only match the direct instances, we use isa! instead. Given the previous organisation example, if we were to only match the direct instances of organisation, we would write the match clause like so.

[tab:Graql] ```graql match $rr isa! romantic-relationship; get $rr; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("rr").isa("romantic-relationship") ).get("rr"); ``` [tab:end]

This query matches only the direct instances of romantic-relationship. That means the instances of open-relation, domestic-relation and complicated-relation (which all subtype romantic-relationship) would not be included.

One particular instance

Grakn assigns an auto-generated id to each instance. Although this id is generated by Grakn solely for internal use, it is indeed possible to find an instance with its Grakn id. To do so, we use the iid keyword followed by the iid assigned to the instance by Grakn.

[tab:Graql] ```graql match $x iid 0x966e80018000000000000000; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("x").iid("0x966e80018000000000000000") ).get("x"); ``` [tab:end]

Comparators

When matching an instance of an attribute type based on its value or simply comparing two variables, the following comparators may be used: ==, !=, >, >=, < and <=.

Match Schema Concepts

In this section, we learn how we can use the match keyword to find patterns in the schema of a Grakn knowledge graph. Matching concepts of a schema is always preceded by get;. In the next section, we learn about how to use the get keyword.

Having fully understood the schema concepts and how they are defined, you can think of the following match examples as fill-in-the-blank questions, where the-blank is a Graql variable and the sentences are different parts of the schema statements.

Direct and indirect subtypes of a given type

To match all schema concepts of a given type, all the way down the type hierarchy, we use the sub keyword.

[tab:Graql] ```graql match $x sub post; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query_a = Graql.match( var("x").sub("post") ).get("x"); ``` [tab:end]

Running the above query on the social_network knowledge graph, returns the post concept type itself, as well as all concept types that are subtypes of post, directly (i.e. media, comment, album and status-update) and indirectly (i.e. photo and video).

Direct subtypes of a given type

To match the schema concepts of a given type, all the way down its type hierarchy, we use the sub! keyword.

[tab:Graql] ```graql match $x sub! post; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query_a = Graql.match( var("x").subX("post") ).get("x"); ``` [tab:end]

Running the above query on the social_network knowledge graph, returns the post concept type itself, as well as the concept types that subtype post directly (i.e. media, comment, album and status-update) or through any of its subtypes (i.e. photo and video).

A given type

To match only the given type and not any of its subtypes, we use the type keyword.

[tab:Graql] ```graql match $x type post; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query_a = Graql.match( var("x").type("post") ).get("x"); ``` [tab:end]

Running the above query, returns only the concept type that has the label post.

Roles of a given relation

Given a particular relation, we can use the relates keyword to match all roles related to the given relation type.

[tab:Graql] ```graql match employment relates $x; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( type("employment").relates(var("x")) ).get("x"); ``` [tab:end]

This matches all roles of the employment relation - employer and employee.

Subroles of a given role in a super-relation

When we learned about subtyping relations, we saw that a role related to a sub-relation is linked to a corresponding parent’s role using the as keyword. We can use the same keyword in a match clause to match the corresponding role in the given sub-relation.

[tab:Graql] ```graql match friend-request relates $x as located; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( type("friend-request").relates(var("x"), "subject") ).get("x"); ``` [tab:end]

This matches all the roles that correspond to the subject role of the relation which friend-request subtypes. In this case, the super-relation being request and the matched role being friendship.

Role players of a given role

Given a role, we can match the concept types that play the given role by using the plays keyword.

[tab:Graql] ```graql match $x plays employment:employee; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("x").plays("employment", "employee") ).get("x"); ``` [tab:end]

This matches all concept types that play the role employee in any relation.

Owners of a given attribute

Given an attribute type, we can match the concept types that own the given attribute type by using the has keyword.

[tab:Graql] ```graql match $x has title $t; get $x; ``` [tab:end] [tab:Java] ```java GraqlMatch.Filtered query = Graql.match( var("x").has("title", var("t")) ).get("x"); ``` [tab:end]

This matches all concept types that own title as their attribute.

Examples

To see some get queries powered by complex and expressive match clauses, check out the examples of querying a sample knowledge graph.

Clients Guide

[Note] **For those developing with Client [Java](../client-api/java)**: Executing a query that contains a `match` clause, is as simple as calling the [`query().match()`](../client-api/java) method on a transaction and passing the query object to it.
[Note] **For those developing with Client [Node.js](../client-api/nodejs)**: Executing a query that contains a `match` clause, is as simple as passing the Graql(string) query to the `query().match()` function available on the [`transaction`](../client-api/nodejs#transaction) object.
[Note] **For those developing with Client [Python](../client-api/python)**: Executing a query that contains a `match` clause, is as simple as passing the Graql(string) query to the `query().match()` method available on the [`transaction`](../client-api/python#transaction) object.

Summary

We learned how to use the match clause to write intuitive statements that describe a desired pattern in the knowledge graph and fill in the variables that hold the data we would like to acquire.

Next, we learn how to use the match clause in conjunction with Graql queries to carry out instructions - starting with the get query.