# Lesson 7: Understanding query patterns

## [](#_patterns_as_constraints)[Patterns as constraints](../7.1-patterns-as-constraints/index.md)

*   A **pattern** comprises a [conjunction](https://en.wikipedia.org/wiki/Logical_conjunction) of any number of consecutive statements.
    
*   A pattern is equivalent to a list of **constraints** about the **terms** involved, which must be **simultaneously** satisfied. A term can be either a variable or a literal.
    
*   Type inference determines the type of each variable by solving the pattern as a **constraint satisfaction** problem.
    
*   If a variable in a query pattern has no possible types, the pattern fails validation and an exception is thrown.
    

## [](#_relation_patterns)[Relation patterns](../7.2-relation-patterns/index.md)

*   A relation with any number of role players can be represented using a **relation tuple** with the same number of elements. This allows for unary, binary, ternary, and n-ary relations.
    
    ```typeql
    n-ary-relation (role-1: $a, role-2: $b, role-3: $c, role-4: $d, ...);
    ```
    
*   role players can be omitted from relation tuples, allowing **partial tuple** representations of relations. This will match those relations regardless of the omitted role players.
    
    ```typeql
    ternary-relation (role-1: $a, role-2: $b);
    ```
    
*   Roles can be omitted from relation tuples, allowing TypeDB to use **role inference** to infer them. This will match the role players in any combination of the relation’s roles.
    
    ```typeql
    example-relation ($a, $b);
    ```
    
*   A relation’s type can be omitted after a relation tuple, allowing TypeDB to use **type inference** to infer the possible types. This will match any relations with the supplied role names.
    
    ```typeql
    (role-1: $a, role-2: $b);
    ```
    

## [](#_logical_operators)[Logical operators](../7.3-logical-operators/index.md)

*   A [disjunction](https://en.wikipedia.org/wiki/Logical_disjunction) of patterns is made by placing those patterns in separate **blocks** interleaved with the `or` keyword, terminated with a `;` delimiter.
    
    ```typeql
    {
        # branch 1
    } or {
        # branch 2
    };
    ```
    
*   A [negation](https://en.wikipedia.org/wiki/Negation) of a pattern is made by placing it in a block preceded by the `not` keyword and followed by a `;` delimiter.
    
    ```typeql
    not {
        # negated pattern
    };
    ```
    
*   An optional pattern of a pattern is made by placing it in a block preceded by the `try` keyword and followed by a `;` delimiter. Optionals let you do **partial** matching:
    
    ```typeql
    try {
        # optional pattern
    };
    ```
    
*   An `is` statement is used to specify that two variables represent the same data object.
    
    ```typeql
    $a is $b;
    ```
    

## [](#_value_comparisons)[Value comparisons](../7.4-value-comparisons/index.md)

*   The **equality operators** `==` and `!=` are used to compare values of all types.
    
    ```typeql
    $attribute-1 == $attribute-2;
    ```
    
*   The **ordering operators** `>`, `>=`, `<`, and `<=` are used to compare values of all types.
    
    ```typeql
    $attribute-1 > $attribute-2;
    ```
    
*   The `contains` operator is used to specify that one string contains another string in a case-insensitive manner.
    
    ```typeql
    $string contains "sub-string";
    ```
    
*   The `like` operator is used to specify that a string matches a Regex.
    
    ```typeql
    $string like "^regex pattern$";
    ```
    

## [](#_value_expressions)[Value expressions](../7.5-value-expressions/index.md)

*   The **assignment operator** `let $var = <expression>` is used to specify the value of a computed variable.
    
*   The **assignment iterator** `let $var in <expression>` is used to specify the value of a of iterating over a computed iterable, one at a time
    
*   Numeric values can be computed using **arithmetic operators** `^`, `*`, `/`, `%`, `+`, and `-`, as well as **arithmetic functions** `min`, `max`, `round`, `floor`, `ceil`, and `abs` inside expressions
    

## [](#_solution_set_semantics)[Solution set semantics](../7.6-solution-set-semantics/index.md)

*   If a query pattern can be split into multiple independent sub-patterns with no shared variables, then those sub-patterns are resolved against the schema independently, and all possible combinations of data matching each sub-pattern are returned.
    
*   If the constraints on two variables are identical, then each pair of data instances matched by those variables will be returned twice.
    
*   These behaviours can lead to unintended query results if not accounted for.
    

## [](#_further_learning)Further learning

[Lesson 8: Composing clauses](../../8-composing-clauses/index.md)

Learn how to structure query results in the optimal manner, covering result grouping, aggregations, sorting, and pagination.

[Lesson 9: Modeling schemas](../../9-modeling-schemas/index.md)

Learn how to design schemas for TypeDB using the conceptual PERA model, including common design patterns and pitfalls.

[Reference: Patterns](../../../typeql-reference/patterns/index.md)

Read the TypeQL patterns reference, covering conjunctions, disjunctions, negations, and pattern matching behaviour.

[Solution set semantics](../7.6-solution-set-semantics/index.md) [8\. Composing clauses](../../8-composing-clauses/index.md)

[Edit on GitHub](https://github.com/typedb/typedb-docs/edit/3.x-development/academy/modules/ROOT/pages/7-understanding-query-patterns/summary.adoc) Edit this page on GitHub.