Designing Cypher (a graph query language) Narrated by Tobias - - PowerPoint PPT Presentation

designing cypher
SMART_READER_LITE
LIVE PREVIEW

Designing Cypher (a graph query language) Narrated by Tobias - - PowerPoint PPT Presentation

Designing Cypher (a graph query language) Narrated by Tobias Lindaaker, Developer at Neo Technology tobias@neotechnology.com #neo4j,#cypher @thobe Once upon a time ~2001 in the kingdom of Sweden ~2001 there was a DBMS that had some


slide-1
SLIDE 1

Designing Cypher

(a graph query language)

Narrated by Tobias Lindaaker, Developer at Neo Technology tobias@neotechnology.com #neo4j,#cypher @thobe

slide-2
SLIDE 2

Once upon a time…

~2001

slide-3
SLIDE 3

in the kingdom of Sweden

~2001

slide-4
SLIDE 4

there was a DBMS that had some interesting things going for it…

~2001

slide-5
SLIDE 5

a few years later…

This presentation has been given at StrangeLoop, the video is online: youtu.be/l-n8yj6_RgU This is a Stand-Alone Sequel

~2016

slide-6
SLIDE 6

The Precursors to Cypher

Embedded Java API HTTP API
 server model 2001 2006 2010 Custom code deployment 2011 (July) First release

  • f Cypher
slide-7
SLIDE 7

The Origin of Cypher

slide-8
SLIDE 8

(query)--[MODELED_AS]--->(drawing) ^ | | | [IMPLEMENTS] [TRANSLATED_TO] | | | v (code)<-[IN_COMMENT_OF]-(ascii art)

The Origin of Cypher

slide-9
SLIDE 9

(query)--[MODELED_AS]--->(drawing) ^ | | | [IMPLEMENTS] [TRANSLATED_TO] | | | v (code)<-[IN_COMMENT_OF]-(ascii art)

MATCH (query)-[:MODELED_AS]->(drawing), (code)-[:IMPLEMENTS]->(query), (drawing)-[:TRANSLATED_TO]->(ascii_art) (ascii_art)-[:IN_COMMENT_OF]->(code) WHERE query.id = {query_id} RETURN code.source

The Origin of Cypher

slide-10
SLIDE 10

v1: Read Only

START john=node:Person(name="John") MATCH (john)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) WHERE NOT (john)-[:KNOWS]-(foaf) RETURN foaf

July 2011 (neo4j 1.4)

slide-11
SLIDE 11

v2: Graph write no update of search structures

START john=node:Person(name="John") MATCH (john)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) WHERE NOT (john)-[:KNOWS]-(foaf) AND NOT (john)-[:RECOMMENDATION]->(foaf) CREATE (john)-[:RECOMMENDATION]->(foaf) RETURN foaf

Oct 2012 (neo4j 1.8)

slide-12
SLIDE 12

Neo4j 2.0: labels and proper indexes Cypher “feature complete”

MATCH (john:Person{name:"John"}), (john)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) WHERE NOT (john)-[:KNOWS]-(foaf) MERGE (john)-[:RECOMMENDATION]->(foaf)

(neo4j 2.0) Dec 2013

slide-13
SLIDE 13

A brief Cypher overview

Pattern matching:
 MATCH (n), (a)-[:REL]->(b)
 + filtering:
 WHERE n=b AND a.val < n.val Returning results
 RETURN x.name AS name
 ORDER BY x.score LIMIT 10 Creating data:


CREATE (p:Person{name:”Tobias”})

Updating data:
 SET n.name = ”John” Deleting data:
 REMOVE p.age
 DELETE n Carrying results from a query into a new
 MATCH (a)-[:KNOWS]->(b)
 WITH a, avg(b.age) AS frAge
 WHERE frAge > 15
 MATCH (a)<-[:FOLLOWS]-(c)
 RETURN c.name OPTIONAL MATCH
 Match-or-null MERGE
 Match-or-create
 with ON MATCH and ON CREATE
 to perform updates

slide-14
SLIDE 14

Multiple versions

Put the version in the query, and support multiple versions

  • f Cypher

in the Neo4j Server CYPHER 2.0 MATCH (n) RETURN n

slide-15
SLIDE 15

Improve based on user feedback

… good, but not as good as we hoped…

photo credits: Columbia Journalism Review

slide-16
SLIDE 16

Query caching - amortise cost of

  • ptimisation
slide-17
SLIDE 17

Whole program analysis

MATCH (john:Person{name:"John"}), (john)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) RETURN friend.name

slide-18
SLIDE 18

Whole program analysis

MATCH (john:Person{name:"John"}), (john)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) RETURN friend.name

  • [:KNOWS]-(foaf)
slide-19
SLIDE 19

Recent additions: Procedures

CALL dbms.listProcedures()
 YIELD name, signature, description MATCH (me:Person{name:{myName}}),
 (me)-[:KNOWS]-()-[:KNOWS]-(foaf)
 WHERE NOT (me)-[:KNOWS]-(foaf)
 CALL apoc.load.jdbc('mysql:…',
 "SELECT * FROM people WHERE id = "
 + foaf.id) YIELD row
 RETURN foaf.name, row.address

slide-20
SLIDE 20

it isn’t all roses

slide-21
SLIDE 21

Semantically different things look similar

MATCH (n:Measurement) RETURN abs(n.value) MATCH (n:Measurement) RETURN avg(n.value) MATCH (a:Foo{key:{a}}), (b:Foo{key:{b}}),
 p=(a)-[:BAR*1..]-(b)
 WHERE all(n in nodes(p) WHERE n.value > {m})
 RETURN length(p)

slide-22
SLIDE 22

Constructs with intricate semantics

Deprecated:
 MATCH (a:Foo{key:{a}}), (b:Foo{key:{b}})
 CREATE UNIQUE (a)-[:KNOWS]-(u)-[:KNOWS]-(b) Better:
 MATCH (a:Foo{key:{a}}), (b:Foo{key:{b}})
 MERGE (a)-[:KNOWS]-(u)-[:KNOWS]-(b)

slide-23
SLIDE 23

Constructs with intricate semantics

MATCH (a)-->(b)<--(c)
 RETURN a.key,b.key,c.key vs MATCH (a)-->(b)
 MATCH (b)<--(c)
 RETURN a.key,b.key,c.key key:x key:y

slide-24
SLIDE 24

Constructs with intricate semantics

MATCH (a)-->(b)<--(c)
 RETURN a.key,b.key,c.key vs MATCH (a)-->(b)
 MATCH (b)<--(c)
 RETURN a.key,b.key,c.key key:x key:y <no rows> a.key:’x’, b.key:’y’, c.key:’x’

slide-25
SLIDE 25

Constructs with intricate semantics

MATCH (a)-->(b)<--(c)
 RETURN a.key,b.key,c.key vs MATCH (a)-->(b)
 MATCH (b)<--(c)
 RETURN a.key,b.key,c.key key:x key:y <no rows> a.key:’x’, b.key:’y’, c.key:’x’ MATCH (a)-[x]->(b)
 MATCH (b)<-[y]-(c)
 WHERE x <> y
 RETURN a.key,b.key,c.key

slide-26
SLIDE 26

“Syntactic sugar” vs single canonical syntax

MATCH (n) WHERE n.foo = "bar"
 vs
 MATCH (n{foo: "bar"}) MATCH (n WHERE foo < 10)
 vs
 MATCH (n) WHERE n.foo < 10

slide-27
SLIDE 27

Predicates on variable length paths

MATCH (a)-[r*]->(b)
 WHERE all(x IN r WHERE x.weight > 0) would be simpler if it could be written as: MATCH (a)-[r* WHERE weight > 0]->(b) although there are other problems that would come from that…

slide-28
SLIDE 28

LOAD CSV will be replaced

LOAD CSV WITH HEADERS FROM "some.csv" AS line CALL apoc.load.csv("some.csv")
 YIELD map AS line

slide-29
SLIDE 29

Parameters avoid SQL injection

slide-30
SLIDE 30

Labels and Relationship Types cannot be passed as parameters

MATCH (n:{label}) SET n:{label}

slide-31
SLIDE 31 6/20/2016 https://s3.amazonaws.com/artifacts.opencypher.org/railroad/Cypher.svg https://s3.amazonaws.com/artifacts.opencypher.org/railroad/Cypher.svg 1/1 QueryOptions CREATE Index DROP Index CREATE UniqueConstraint DROP UniqueConstraint CREATE NodePropertyExistenceConstraint DROP NodePropertyExistenceConstraint CREATE RelationshipPropertyExistenceConstraint DROP RelationshipPropertyExistenceConstraint LoadCSV Start Match Unwind Merge Create Set Delete Remove Foreach With Return ALL UNION BulkImportQuery ;
  • penCypher

Opening the language design process Implementations for other platforms Compatibility test suite Grammar specification Reference implementation Defining the next version of Cypher

https://github.com/openCypher/openCypher

slide-32
SLIDE 32

Future features

Cypher keeps evolving You can get involved through openCypher

slide-33
SLIDE 33

Sub queries are powerful

MATCH (me:Person{name:{myName}}),
 (me)-[:FRIEND]-(friend)
 
 WITH me, collect(friend) AS friends
 
 MATCH (me)-[:ENEMY]-(enemy)
 RETURN me, friends, collect(enemy) AS enemies

slide-34
SLIDE 34

Sub-queries for side effects

MATCH (me:Person{name:{myName}}),
 (me)-[:FRIEND]-(friend)
 WITH me, collect(friend) AS friends
 MATCH (me)-[:ENEMY]-(enemy)
 
 DO {
 UNWIND friends AS friend
 MERGE (friend)-[:ENEMY]-(enemy)
 } DO will replace FOREACH

slide-35
SLIDE 35

Existential sub-queries

MATCH (actor:Actor)
 WHERE EXISTS {
 (actor)-[:ACTED_IN]->(movie),
 (other:Actor)-[:ACTED_IN]->(movie)
 WHERE other.name = actor.name
 AND actor <> other
 }
 RETURN actor

slide-36
SLIDE 36

More Sub-queries

MATCH (me:User{name:{username}})-[:FOLLOWS]->(user)
 WHERE user.country = {country}
 MATCH {
 // authored tweets
 MATCH (user)<-[:AUTHORED]-(tweet:Tweet)
 RETURN tweet, tweet.time AS time
 
 UNION
 
 // favorited tweets
 MATCH (user)<-[:HAS_FAVOURITE]-(favorite)-[:TARGETS]->(tweet:Tweet)
 RETURN tweet, favourite.time AS time
 }
 RETURN DISTINCT tweet
 ORDER BY time DESC
 LIMIT 100

slide-37
SLIDE 37

Projections and comprehension

MATCH (person:Person{ssn:{mySSN}}),
 (person)-[emp:EMPLOYED_BY]->(employer)
 WHERE NOT exists(emp.endDate)
 WITH person, employer.name AS employer
 ORDER BY emp.startDate DESC LIMIT 1
 RETURN person{
 .ssn,
 .firstName,
 .lastName,
 employer,
 friends: [
 MATCH (person)-[:FRIEND]-(friend)
 WHERE friend.age > 12
 RETURN friend{
 .ssn,
 .firstName,
 .lastName
 }
 ]} Inspired by Facebook’s GraphQL
 
 
 Returns a single column ‘person’ containing:
 
 {
 ssn: “192168-0001”,
 firstName: “John”,
 lastName: “Smith”,
 employer: “The Company, Inc.”,
 friends: [
 {ssn: “009933-1126”,
 firstName: “Marty”,
 lastName: “McFly”},
 {ssn: “123987-4506”,
 firstName: “Emmet”,
 lastName: “Brown”},
 ]
 }

slide-38
SLIDE 38

The End