intro to cypher

37
Cypher Query Language Chicago Graph Database Meet-Up Max De Marzi Updated for Neo4j 2.x by Brian Underwood

Upload: brian-underwood

Post on 17-Jul-2015

116 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Intro to Cypher

Cypher Query

Language

Chicago Graph Database Meet-Up

Max De Marzi

Updated for Neo4j 2.x by Brian Underwood

Page 2: Intro to Cypher

What is Cypher?

• Graph Query Language for

Neo4j

• Aims to make querying simple

Page 3: Intro to Cypher

Motivation

Why Cypher?

• Existing Neo4j query mechanisms were

not simple enough

• Too verbose (Java API)

• Too prescriptive (Gremlin)

Page 4: Intro to Cypher

Motivation

SQL?

• Unable to express paths

• these are crucial for graph-based

reasoning

• Neo4j is schema/table free

Page 5: Intro to Cypher

Design Decisions

Pattern matching

Page 6: Intro to Cypher

Design Decisions

Pattern matching

A

B C

Page 7: Intro to Cypher

Design Decisions

Pattern matching

Page 8: Intro to Cypher

Design Decisions

Pattern matching

Page 9: Intro to Cypher

Design Decisions

Pattern matching

Page 10: Intro to Cypher

Design Decisions

Pattern matching

Page 11: Intro to Cypher

Design Decisions

ASCII-art patterns

() --> ()

Page 12: Intro to Cypher

Design Decisions

Directed relationship

(A) --> (B)

A B

Page 13: Intro to Cypher

Design Decisions

Undirected relationship

(A) -- (B)

A B

Page 14: Intro to Cypher

Design Decisions

specific relationships

A -[:LOVES]-> B

A BLOVE

S

Page 15: Intro to Cypher

Design Decisions

Joined paths

A --> B --> C

A B C

Page 16: Intro to Cypher

Design Decisions

multiple paths

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

A

B C

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

Page 17: Intro to Cypher

Design Decisions

Variable length paths

A -[*]-> B

A B

A B

A B

...

Page 18: Intro to Cypher

Design Decisions

Familiar for SQL users

select

from

where

group

by

order by

match

where

return

Page 19: Intro to Cypher

MATCH

SELECT *

FROM people

WHERE people.firstName = “Max”

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

RETURN max

MATCH (max:Person)

WHERE max.firstName = ‘Max’

RETURN max

Page 20: Intro to Cypher

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

Page 21: Intro to Cypher

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

Page 22: Intro to Cypher

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’

Page 23: Intro to Cypher

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

[user_skill]-> (skill:Skill)

RETURN skill, user_skill

Page 24: Intro to Cypher

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;

Page 25: Intro to Cypher

Complicated Match

Some UGLY recursive self join on the

groups table

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

{name: ‘Max’})

RETURN group

Page 26: Intro to Cypher

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

Page 27: Intro to Cypher

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

Page 28: Intro to Cypher

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

Page 29: Intro to Cypher

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

Page 30: Intro to Cypher

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)

Page 31: Intro to Cypher

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

Page 32: Intro to Cypher

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)

Page 33: Intro to Cypher

Uses

Recommend Friends

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

WHERE ID(me) = {node_id}

RETURN foaf.name

Page 34: Intro to Cypher

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

Page 35: Intro to Cypher

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

Page 36: Intro to Cypher

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

Page 37: Intro to Cypher

Thanks for Listening!

Questions?

maxdemarzi.com