Cypher
Upcoming SlideShare
Loading in...5
×
 

Cypher

on

  • 18,699 views

 

Statistics

Views

Total Views
18,699
Views on SlideShare
5,788
Embed Views
12,911

Actions

Likes
17
Downloads
243
Comments
1

20 Embeds 12,911

http://maxdemarzi.com 8137
http://nosql.mypopescu.com 3986
http://architects.dzone.com 524
http://neo4j.tw 96
http://www.twylah.com 60
http://coderwall.com 42
http://feeds.feedburner.com 17
http://www.shisoft.net 12
http://www.hanrss.com 11
http://www.newsblur.com 7
https://www.google.com 3
http://webcache.googleusercontent.com 3
https://twitter.com 3
http://tweetedtimes.com 2
http://feedproxy.google.com 2
http://translate.googleusercontent.com 2
http://www.the-movies.net 1
http://www.dzone.com 1
http://www.acushare.com 1
http://www.google.fr 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • There existed a number of different ways to query a graph database. This one aims to make querying easy, and to produce queries that are readable. We looked at alternatives - SPARQL, SQL, Gremlin and other...

Cypher Cypher Presentation Transcript

  • Cypher Query Language Chicago Graph Database Meet-Up Max De Marzi
  • What is Cypher?• Graph Query Language for Neo4j• Aims to make querying simple
  • Why Cypher? • Existing Neo4j query mechanisms were not simple enough • Too verbose (Java API) • Too prescriptive (Gremlin)
  • SQL? • Unable to express paths • these are crucial for graph-based reasoning • Neo4j is schema/table free
  • SPARQL? • SPARQL designed for a different data model • namespaces • properties as nodes • high learning curve
  • Design
  • Design Decisions Declarative Most of the time, Neo4j knows better than you Imperative Declarative follow relationship specify starting pointbreadth-first vs depth-first specify desired outcome explicit algorithm algorithm adaptable based on query
  • 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 LOVES A B A -[:LOVES]-> B
  • Design Decisions Joined paths A B C A --> B --> C
  • Design Decisions multiple paths A B C A --> B --> C, A --> C A --> B --> C <-- A
  • Design Decisions Variable length paths A B A B A B ... A -[*]-> B
  • Design Decisions Optional relationships A B A -[?]-> B
  • Design Decisions Familiar for SQL users select start from match where where group by return order by
  • STARTSELECT *FROM PersonWHERE firstName = “Max”START max=node:persons(firstName = “Max”)RETURN max
  • MATCHSELECT skills.*FROM usersJOIN skills ON users.id = skills.user_idWHERE users.id = 101START user = node(101)MATCH user --> skillsRETURN skills
  • Optional MATCHSELECT skills.*FROM usersLEFT JOIN skills ON users.id = skills.user_idWHERE users.id = 101START user = node(101)MATCH user –[?]-> skillsRETURN skills
  • SELECT skills.*, user_skill.*FROM usersJOIN user_skill ON users.id = user_skill.user_idJOIN skills ON user_skill.skill_id = skill.id WHEREusers.id = 1
  • START user = node(1)MATCH user -[user_skill]-> skillRETURN skill, user_skill
  • IndexesUsed as multiple starting points, not to speedup any traversalsSTART a = node:nodes_index(type=User) MATCHa-[r:knows]-bRETURN ID(a), ID(b), r.weight
  • http://maxdemarzi.com/2012/03/16/jung-in-neo4j-par
  • Complicated MatchSome UGLY recursive self join on the groupstableSTART max=node:person(name=“Max")MATCH group <-[:BELONGS_TO*]- maxRETURN group
  • WhereSELECT person.*FROM personWHERE person.age >32 OR person.hair = "bald"START person = node:persons("name:*") WHEREperson.age >32 OR person.hair = "bald"RETURN person
  • ReturnSELECT person.name, count(*)FROM PersonGROUP BY person.nameORDER BY person.nameSTART person=node:persons("name:*") RETURNperson.name, count(*)ORDER BY person.name
  • Order By, ParametersSame as SQL{node_id} expected as part of requestSTART me = node({node_id})MATCH (me)-[?:follows]->(friends)-[?:follows]->(fof)-[?:follows]->(fofof)-[?:follows]->othersRETURN me.name, friends.name, fof.name, fofof.name, count(others)ORDER BY friends.name, fof.name, fofof.name, count(others) DESC
  • http://maxdemarzi.com/2012/02/13/visualizing-a-netw
  • Graph FunctionsSome UGLY multiple recursive self and inner joins onthe user and all related tablesSTART lucy=node(1000), kevin=node(759) MATCH p= shortestPath( lucy-[*]-kevin ) RETURN p
  • Aggregate FunctionsID: get the neo4j assigned identifierCount: add up the number of occurrencesMin: get the lowest valueMax: get the highest valueAvg: get the average of a numeric valueDistinct: remove duplicatesSTART me = node:nodes_index(type = user)MATCH (me)-[r?:wrote]-()RETURN ID(me), me.name, count(r), min(r.date), max(r.date)" ORDERBY ID(me)
  • FunctionsCollect: put all values in a listSTART a = node:nodes_index(type=User)MATCH a-[:follows]->bRETURN a.name, collect(b.name)
  • http://maxdemarzi.com/2012/02/02/graph-visualizatio
  • Combine FunctionsCollect the ID of friendsSTART me = node:nodes_index(type = user)"MATCH (me)<-[r?:wrote]-(friends)RETURN ID(me), me.name, collect(ID(friends)), collect(r.date)ORDER BY ID(me)
  • http://maxdemarzi.com/2012/03/08/connections-in-time/
  • UsesRecommend FriendsSTART me = node({node_id})MATCH (me)-[:friends]->(friend)-[:friends]->(foaf)RETURN foaf.name
  • UsesSix Degrees of Kevin BaconLength: counts the number of nodes along a pathExtract: gets the nodes/relationships from a pathSTART me=node({start_node_id}), them=node({destination_node_id})MATCH path = allShortestPaths( me-[?*]->them )RETURN length(path), extract(person in nodes(path) : person.name)
  • UsesSimilar UsersUsers who rated same items within 2 points.Abs: gets absolute numeric valueSTART me = node(user1)MATCH (me)-[myRating:RATED]->(i)<-[otherRating:RATED]-(u)WHERE abs(myRating.rating-otherRating.rating)<=2RETURN u
  • Boolean OperationsItems with a rating > 7 that similar users rated, but I have notAnd: this and that are trueOr: this or that is trueNot: this is falseSTART me=node(user1),        similarUsers=node(3) (result received in the first query)MATCH (similarUsers)-[r:RATED]->(item)WHERE r.rating > 7 AND NOT((me)-[:RATED]->(item)) RETURN itemhttp://thought-bytes.blogspot.com/2012/02/similarity-based-recommendation
  • PredicatesALL: closure is true for all itemsANY: closure is true for any itemNONE: closure is true for no itemsSINGLE: closure is true for exactly 1 itemSTART london = node(1), moscow = node(2)MATCH path = london -[*]-> moscowWHERE all(city in nodes(path) wherecity.capital = true)
  • Design Decisions Parsed, not an internal DSL Execution Semantics Serialisation Type System Portability
  • Design Decisions Database vs Application Design Goal: single user interaction expressible as single query Queries have enough logic to find required data, not enough to process it
  • Implementation
  • Implementation • Recursive matching with backtrackingSTART x=... MATCH x-->y, x-->z, y-->z, z-->a-->b, z-->b
  • Implementation Execution Planstart n=node(0) Cypher is Pipesreturn n lazily evaluatedParameters() pulling from pipes underneathNodes(n)Extract([n])ColumnFilter([n])
  • Implementation Execution Planstart n=node(0)match n-[*]-> breturn n.name, n, count(*)order by n.ageParameters()Nodes(n)PatternMatch(n-[*]->b)Extract([n.name, n])EagerAggregation( keys: [n.name, n], aggregates: [count(*)])Extract([n.age])Sort(n.age ASC)ColumnFilter([n.name,n,count(*)])
  • Implementation Execution Planstart n=node(0)match n-[*]-> breturn n.name, n, count(*)order by n.nameParameters()Nodes(n)PatternMatch(n-[*]->b)Extract([n.name, n])Sort(n.name ASC,n ASC)EagerAgregation( keys: [n.name, n], aggregates: [count(*)])ColumnFilter([n.name,n,count(*)])
  • Thanks for Listening! Questions?maxdemarzi.com