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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("p").isa("person") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("p").isa("person").has("full-name", var("n")) ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("emp").isa("employment").rel("employer", "x").rel("employee", "y") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("emp").isa("employment").rel("employer", "x").rel("employee", "y").has("reference-id", var("ref")) ).get(); ``` [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 roleplayers 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; get; ``` [tab:end] [tab:Java] ```java GraqlGet 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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("fr").isa("friendship").rel("x").rel("y") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("x").val("like") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("x").isa("nickname").val("Mitzi") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("phone-number").contains("+44") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("phone-number").regex("(Miriam Morton|Solomon Tran)") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("p").isa("person").has("nickname", var("nn")).has("full-name", var("fn")) ).get(); ``` [tab:end]

Owners with attributes of given values

We can also match instances that own an attribute with a specific value.

[tab:Graql] ```graql match $p isa person, has nickname "Mitzi", has phone-number contains "+44"; get; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("p").isa("person").has("nickname", "Mitzi").has("phone-number", Graql.contains("+44")) ).get(); ``` [tab:end]

But if in this example, we still want to know how old exactly each John is? we can separate the condition like so.

[tab:Graql] ```graql match $p isa person, has nickname "Mitzi", has phone-number $pn; $pn contains "+44"; get; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("p").isa("person").has("nickname", "Mitzi").has("phone-number", var("pn")), var("pn").contains("+44") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("p").isa("person").has("full-name", var("fn")), or( var("fn").contains("Miriam"), var("fn").contains("Solomon") ) ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("rr").isaX("romantic-relationship") ).get(); ``` [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 id keyword followed by the id assigned to the instance by Grakn.

[tab:Graql] ```graql match $x id V41016; get; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("x").id("V41016") ).get(); ``` [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, were 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; ``` [tab:end] [tab:Java] ```java GraqlGet query_a = Graql.match( var("x").sub("post") ).get(); ``` [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, only one level down the type hierarchy, we use the sub! keyword.

[tab:Graql] ```graql match $x sub! post; get; ``` [tab:end] [tab:Java] ```java GraqlGet query_a = Graql.match( var("x").subX("post") ).get(); ``` [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).

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 sub! post; get; ``` [tab:end] [tab:Java] ```java GraqlGet query_a = Graql.match( var("x").subX("post") ).get(); ``` [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; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( type("employment").relates(var("x")) ).get(); ``` [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 location-of-office relates $x as located-subject; get; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( type("location-of-office").relates(var("x")), var("x").sub("located-subject") ).get(); ``` [tab:end]

This matches all the roles that correspond to the located-subject role of the relation which location-of-office subtypes. In this case, the super-relation being location-of-everything and the matched role being located-subject.

Roleplayers 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 employee; get; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("x").plays("employee") ).get(); ``` [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; get; ``` [tab:end] [tab:Java] ```java GraqlGet query = Graql.match( var("x").has("title") ).get(); ``` [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 [`execute()`](../client-api/java#eagerly-execute-a-graql-query) 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()`](../client-api/nodejs#lazily-execute-a-graql-query) 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()`](../client-api/python#lazily-execute-a-graql-query) 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.