intro to cypher

Post on 17-Jul-2015

116 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Cypher Query

Language

Chicago Graph Database Meet-Up

Max De Marzi

Updated for Neo4j 2.x by Brian Underwood

What is Cypher?

• Graph Query Language for

Neo4j

• Aims to make querying simple

Motivation

Why Cypher?

• Existing Neo4j query mechanisms were

not simple enough

• Too verbose (Java API)

• Too prescriptive (Gremlin)

Motivation

SQL?

• Unable to express paths

• these are crucial for graph-based

reasoning

• Neo4j is schema/table free

Design Decisions

Pattern matching

Design Decisions

Pattern matching

A

B C

Design Decisions

Pattern matching

Design Decisions

Pattern matching

Design Decisions

Pattern matching

Design Decisions

Pattern matching

Design Decisions

ASCII-art patterns

() --> ()

Design Decisions

Directed relationship

(A) --> (B)

A B

Design Decisions

Undirected relationship

(A) -- (B)

A B

Design Decisions

specific relationships

A -[:LOVES]-> B

A BLOVE

S

Design Decisions

Joined paths

A --> B --> C

A B C

Design Decisions

multiple paths

A --> B --> C, A --> C

A

B C

A --> B --> C <-- A

Design Decisions

Variable length paths

A -[*]-> B

A B

A B

A B

...

Design Decisions

Familiar for SQL users

select

from

where

group

by

order by

match

where

return

MATCH

SELECT *

FROM people

WHERE people.firstName = “Max”

MATCH (max:Person {firstName: ‘Max’})

RETURN max

MATCH (max:Person)

WHERE max.firstName = ‘Max’

RETURN max

MATCH

SELECT skills.*

FROM users

JOIN skills ON users.id = skills.user_id

WHERE users.first_name = ‘Max’

MATCH (user:User {firstName: ‘Max’}) -->

(skill:Skill)

RETURN skill

OPTIONAL MATCH

SELECT skills.*

FROM users

LEFT JOIN skills ON users.id = skills.user_id

WHERE users.first_name = ‘Max’

MATCH (user:User {firstName: ‘Max’})

OPTIONAL MATCH user –-> (skill:Skill)

RETURN skill

SELECT skills.*, user_skill.*

FROM users

JOIN user_skill ON users.id = user_skill.user_id

JOIN skills ON user_skill.skill_id = skill.id

WHERE users.first_name = ‘Max’

MATCH (user:User {firstName: ‘Max’})-

[user_skill]-> (skill:Skill)

RETURN skill, user_skill

Indexes

Used as multiple starting points, not to

speed up any traversals

CREATE INDEX ON :User(name);

MATCH (a:User {name: ‘Max’})-[r:KNOWS]-b

RETURN ID(a), ID(b), r.weight;

Complicated Match

Some UGLY recursive self join on the

groups table

MATCH group <-[:BELONGS_TO*]- (max:Person

{name: ‘Max’})

RETURN group

Where

SELECT person.*

FROM person

WHERE person.age >32

OR person.hair = "bald"

MATCH (person:Person)

WHERE person.age > 32 OR person.hair =

"bald"

RETURN person

Return

SELECT people.name, count(*)

FROM people

GROUP BY people.name

ORDER BY people.name

MATCH (person:Person)

RETURN person.name, count(*)

ORDER BY person.name

Order By, Parameters

Same as SQL

{node_id} expected as part of request

MATCH (me)-[:follows]->(friends)-[:follows]->(fof)-[:follows]->(fofof)-

[:follows]->others

WHERE ID(me) = {node_id}

RETURN me.name, friends.name, fof.name, fofof.name, count(others)

ORDER BY friends.name, fof.name, fofof.name, count(others) DESC

Graph Functions

Some UGLY multiple recursive self and inner joins

on the user and all related tables

MATCH p = shortestPath( lucy-[*]-kevin )

WHERE ID(lucy) = 1000 AND ID(kevin) = 759

RETURN p

Aggregate FunctionsID: get the neo4j assigned identifier

Count: add up the number of occurrences

Min: get the lowest value

Max: get the highest value

Avg: get the average of a numeric value

Distinct: remove duplicates

MATCH (me:User)-[r:wrote]-()

RETURN ID(me), me.name, count(r), min(r.date), max(r.date)

ORDER BY ID(me)

Functions

Collect: put aggregated values in a list

MATCH (a:User)-[:follows]->b

RETURN a.name, collect(b.name)

Each result row contains a name for each user

and a list of names which that user follows

Combine Functions

Collect the ID of friends

MATCH (me:User)<-[r:wrote]-(friends)

RETURN ID(me), me.name, collect(ID(friends)), collect(r.date)

ORDER BY ID(me)

Uses

Recommend Friends

MATCH (me)-[:friends]->(friend)-[:friends]->(foaf)

WHERE ID(me) = {node_id}

RETURN foaf.name

Uses

Six Degrees of Kevin Bacon

MATCH path = allShortestPaths( me-[*]->them )

WHERE ID(me) = {start_node_id}

AND ID(them) = {destination_node_id}

RETURN length(path),

extract(person in nodes(path) : person.name)

Length: counts the number of nodes along a path

Extract: gets the nodes/relationships from a path

http://thought-bytes.blogspot.com/2012/02/similarity-

based-recommendations-with.html

MATCH (me:User {id: {me_id}}), (similarUser:User),

(similarUsers)-[r:RATED]->(item)

WHERE ID(similarUser) IN {previousResult) AND

r.rating > 7 AND NOT((me)-[:RATED]->(item))

RETURN item

Items with a rating > 7 that similar users rated, but I have not

And: this and that are true

Or: this or that is true

Not: this is false

Boolean Operations

START london = node(1), moscow = node(2)

MATCH path = london -[*]-> moscow

WHERE all(city in nodes(path) where city.capital = true)

Predicates

ALL: closure is true for all items

ANY: closure is true for any item

NONE: closure is true for no items

SINGLE: closure is true for exactly 1 item

Thanks for Listening!

Questions?

maxdemarzi.com

top related