The query mirrors the question
One of the nicest things about a graph query is that it reads almost like the sentence you'd say out loud. The little arrows in the query are literally the strings in the graph — you're describing a shape, and the database goes and finds it.
Most graph queries are built from just a handful of words. Once you know what each one means in plain English, you can read — and write — almost any query you'll meet in this guide. Here's the whole vocabulary you need to follow along:
MATCH— "go find this shape." It's where you draw the pattern of dots and strings you're looking for. Think of it as describing a sketch and asking the database, "show me every place this sketch appears."(parentheses)— a node (a dot). Inside, you can name it (ana), label it (:Person), or pin down a property ({name: 'Ana'}).-[:KNOWS]->— a relationship (a string), with a label and a direction. The arrow shows which way it points: AnaKNOWSBen, not necessarily the other way around.WHERE— "but only the ones that fit this condition." A filter, in plain words: "where the amount is over $10,000," "where the name is Ana."RETURN— "and give me back exactly this." You pick which pieces of the answer you actually want — a name, a count, a whole path.
That's genuinely most of it. Below we'll build from a one-liner up to a fraud ring and a "find by meaning" search — and you'll see those same five words doing all the work.
Who does Ana know?
The query (Cypher)
MATCH (ana:Person {name: 'Ana'})-[:KNOWS]->(friend) RETURN friend.name
In plain English
"Find the person named Ana, follow every KNOWS string going out from her, and give me the names at the other end."
The -[:KNOWS]->
is just an arrow with a label — exactly the string you'd draw on a whiteboard.
Friends of friends who like jazz
The query (Cypher)
MATCH (me)-[:KNOWS]->(friend)-[:KNOWS]->(fof), (fof)-[:LIKES]->(:Genre {name: 'Jazz'}) WHERE me.name = 'Ana' RETURN fof.name
In plain English
"Starting from Ana, follow the people she knows, then the people they know — and of those friends-of-friends, give me the ones who like Jazz."
Two KNOWS arrows in
a row is "two hops out." The shape of the query is the shape of the question.
Which products are bought together?
The query (Cypher)
MATCH (p:Product {name: 'Coffee'})<-[:BOUGHT]-(c)-[:BOUGHT]->(other) RETURN other.name, count(*) AS together ORDER BY together DESC
In plain English
"Find everyone who bought Coffee, see what else those same customers bought, and rank those other products by how often they show up — most-bought-together first."
That's a recommendation engine in
four short lines — no separate system required. The <-[:BOUGHT]-
points back toward the customer; the -[:BOUGHT]-> points
forward again to a different product. You step in one door and out another.
How is Ana connected to Cleo?
The query (Cypher)
MATCH p = shortestPath( (a:Person {name: 'Ana'})-[:KNOWS*]-(c:Person {name: 'Cleo'}) ) RETURN p
In plain English
"Starting at Ana and ending at Cleo, find the shortest chain of acquaintances that links them — and hand me the whole route."
The little * after
KNOWS means "follow this kind of string as many hops as it takes."
shortestPath then keeps only the most direct route. This is the famous
"six degrees of separation" question — answered directly, instead of with a pile
of self-joins.
Spot a fraud ring
The query (Cypher)
MATCH (a:Account)-[:SENT]->(b:Account)-[:SENT]->(c:Account), (c)-[:SENT]->(a) WHERE a.opened > '2026-01-01' RETURN a, b, c
In plain English
"Find three accounts where money flows A → B → C and back to A — a closed loop — and only flag the ones opened recently."
A loop of payments that returns to its start is a classic money-laundering signature. In a graph you literally draw the loop and ask the database to find every place it occurs. In a table-based system this same question is a dreaded multi-way self-join that few people enjoy writing.
Find by meaning, not keywords
The query (Cypher)
MATCH (doc:Document) WHERE doc.embedding <-> $question < 0.25 RETURN doc.title ORDER BY doc.embedding <-> $question LIMIT 5
In plain English
"Take the meaning of my question, compare it to the meaning of every document, and give me the five closest in meaning — not the ones that happen to share the same words."
The <-> measures
how far apart two meanings are (smaller = more alike). That's vector
search — the backbone of modern AI retrieval — running right next to your
connected data, no separate vector database to keep in sync.
Ask the database what it can do
The query (Cypher)
SHOW FUNCTIONS YIELD name, category, description RETURN name, category, description ORDER BY category, name
In plain English
"List everything this database knows how to do — every built-in function, grouped by category, with a plain-English description of each one."
The descriptions live inside the
engine itself, so this list is always current — exactly in sync with what the
running database can actually do. Use SHOW PROCEDURES for the same catalog
of procedures, or the longer form
CALL xg.builtin_functions() YIELD name, category, description for functions
and CALL xg.procedures() YIELD name, category, description for procedures.
That's self-documentation: ask the database, and it answers from its own source of truth.
Pattern, not procedure
Notice what you didn't do in any of those seven queries: you never told the database
how to find the answer — which table to open first, how to join it to the
next, what order to scan. You just drew the shape you wanted and said RETURN.
The engine figures out the fastest way to satisfy the pattern.
That's the deep difference between a graph language and the older table-based style. One describes a destination ("a loop of three accounts," "documents like this question"); the other makes you write the turn-by-turn directions. When the question is about connections, describing the destination is dramatically shorter and easier to get right.
Go deeper: the same idea in GFQL
Cypher isn't the only language xrayGraphDB speaks. The same questions can be expressed in GFQL, a second, data-frame-style query language — handy when you think in pipelines (do this, then this, then this) rather than in patterns.
Take "friends-of-friends who like jazz." In the GFQL way of thinking you'd start from
Ana, take a hop along KNOWS, take another hop along
KNOWS, then filter to the friends-of-friends who have a LIKES
edge into the "Jazz" genre. Each step is a transformation of the set of nodes you're
"standing on" — the same shape as the Cypher version, just written as a sequence
of steps instead of one drawn pattern. People coming from data-frame and notebook
workflows often find this style immediately familiar.
The takeaway isn't "one is better." It's that your team can use whichever reads more naturally to them — pattern-style or pipeline-style — against the very same data, on the very same engine, with no translation layer in between.
Full, runnable examples in both languages — with the exact syntax for vector search, shortest paths, and the analytics functions — live in the docs.