UltipaDocs
Products
Solutions
Resources
Company
Start Free Trial
UltipaDocs
Start Free Trial
  • Introduction
  • GQL vs Other Languages
    • Overview
    • Node and Edge Patterns
    • Path Patterns
    • Quantified Paths
    • Questioned Paths
    • Shortest Paths
    • Graph Patterns
    • Overview
    • Closed Graph
    • Open Graph
    • Graph Sharding and Storage
    • Constraints
    • Unique Identifiers
    • INSERT
    • INSERT OVERWRITE
    • UPSERT
    • SET
    • REMOVE
    • DELETE
    • Query Composition
    • Result Table and Visualization
    • MATCH
    • OPTIONAL MATCH
    • FILTER
    • LET
    • FOR
    • ORDER BY
    • LIMIT
    • SKIP
    • CALL
    • RETURN
    • Composite Query
    • NEXT
    • All Functions
    • Scalar Functions
    • Path Functions
    • Aggregate Functions
    • Mathematical Functions
    • Trigonometric Functions
    • String Functions
    • List Functions
    • Datetime Functions
    • Spatial Functions
    • Type Conversion Functions
    • Table Functions
    • AI & Vector Functions
    • Database Functions
  • Operators
  • Predicates
  • Expressions
    • Index
    • Full-text Index
    • Vector Index
  • Transactions
  • Triggers
  • Query Management
  • Backup and Restore
    • Variables
    • Values and Types
    • Comments
    • Reserved Words
    • Syntactic Notation
  • GQL Conformance
  1. Docs
  2. /
  3. ISO GQL
  4. /
  5. Graph Pattern Matching

Questioned Paths

Overview

A questioned path makes a path pattern optional — it matches zero or one occurrence. This is useful when you want to include a connection in a pattern but it may not always exist.

A questioned path is written by appending ? to a parenthesized path pattern expression.

Syntax
<questioned path pattern> ::=
  "(" <path pattern expression> ")" "?"

The ? quantifier is equivalent to {0,1}. When the path exists, it is included in the result; when it doesn't, the match still succeeds with the optional part absent.

Example Graph

GQL
INSERT (jack:User {_id: "U01", name: "Jack"}),
       (mike:User {_id: "U02", name: "Mike"}),
       (c1:Device {_id: "Comp1"}),
       (c2:Device {_id: "Comp2"}),
       (c3:Device {_id: "Comp3"}),
       (c4:Device {_id: "Comp4"}),
       (jack)-[:Owns]->(c1),
       (mike)-[:Owns]->(c4),
       (c1)-[:Flows {packets: 20}]->(c2),
       (c1)-[:Flows {packets: 30}]->(c4),
       (c2)-[:Flows {packets: 34}]->(c3),
       (c2)-[:Flows {packets: 12}]->(c4),
       (c3)-[:Flows {packets: 74}]->(c4)

Examples

Optional Connection

Find all devices reachable from Comp1 with an optional second hop:

GQL
MATCH ({_id: 'Comp1'})-[:Flows]->(d1:Device)(()-[:Flows]->(d2:Device))?
RETURN d1._id AS firstHop, d2._id AS secondHop

When the second hop exists, d2 contains the device; when it doesn't, d2 is null.

Optional Ownership

Find all devices and optionally their owners:

GQL
MATCH (d:Device)(()<-[:Owns]-(u:User))?
RETURN d._id AS device, u.name AS owner

Devices without an owner still appear in the results with owner as null.