Document oriented access
to a graph database
Using a Neo4j Server Extension
Michael Hunger - @mesirii
http://github.com/je...
Graphs
Graphs are great
• for modeling highly connected domains
• finding patterns to answer questions
• high performance traversa...
Graphs are great
Graphs suck
• for compact access patterns
• use-case specific views
• easy integration in modern webapps
Graphs suck
Documents
Documents are great
• for everything that eats JSON
• especially modern JavaScript based webapps
• as dedicated projection...
Documents are great
{
name:"Michael",
age:39,
children:[„Selina“,“Rana“,"Selma"],
address: { street: „Holbeinstr“, city: „...
Documents suck
• for different projections besides the main use-case
• for connected data
• for cross-document linking
• f...
Documents suck
{
name:"Michael",
age:39,
children:[„Selina“,“Rana“,"Selma"],
address: { street: „Holbeinstr“, city: „Dresd...
Documents suck
{ _id: 1,
name:“Michael“,
works_at: dbref:2
}
{ _id: 2,
name:“Neo Technology“,
employees: [dbref:1]
}
„Link...
What can we do?
• Use a document oriented access layer for a graph database
• Use graph queries whose results project into...
How can we do that?
• Use Cypher in Neo4j 2.0
• Support for literal maps
• Parameters, including maps
Cypher Maps
Cypher & Maps - Results
MATCH (n:User)
WHERE n.name={name}
RETURN n
// returns a map of the node’s properties
RETURN {id: ...
Cypher & Maps - Results (II)
MATCH (n:User)-[:PARENT_OF]->(child)
WHERE n.name={name}
RETURN {name:n.name, children:collec...
Cypher & Maps - Params
CREATE (u:User { name: {p}.name, age: {p}.age})
RETURN u
CREATE (u:User {params})
RETURN u
Some Questions
How can we do that?
• Create a RESTful API to
• Provide endpoints that represent on Cypher queries
• Use GET, POST with pa...
How do we implement it?
• Add a Neo4j-Server-Extension
• Jersey JAX-RS
• Save queries in graph properties
• Execute querie...
What does it look like?
What does it look like?
• Examples for
• Managing endpoints
• Querying Endpoints
• Writing to Endpoints
Create Endpoint
PUT /cypher-rs/users
Body: match (n:User) where n.name={name} return n
--> 201 Location: /cypher-rs/users
...
GET, POST - Reads
GET Request
GET /cypher-rs/users?name=Andres
--> 200
{"name":"Andres",
"age":21,"children":["Cypher","L.","N."]}
GET /cyph...
POST Request - Read
POST /cypher-rs/users
Content-type: application/json
Body: {"name":"Andres"}
--> 200
{"name":"Andres",...
POST Request - Read (II)
POST /cypher-rs/users
Content-type: application/json
Body: [{"name":"Andres"},{"name":"Peter"},{"...
POST - Write
POST Request - Write JSON
POST /cypher-rs/create-user
Content-type: application/json
Body: {"name":"Andres","age":21}
--> ...
POST Request - Write JSON (II)
POST /cypher-rs/create-user
Content-type: application/json
Body: [{"name":"Andres","age":21...
POST Request - Write CSV (III)
POST /cypher-rs/create-user[?batch=20000&delim=,]
Content-type: text/plain
Body: name,agenA...
More Management
Delete Endpoint
DELETE /cypher-rs/users
--> 200
List Endpoints
GET /cypher-rs
--> 200
[„create-users“, „users“]
Inspect Endpoint
GET /cypher-rs/users/query
--> 200
match (n:User) where n.name={name} return n
Results
Possible Results
single column, single row!
{"name":"Andres","age":21,"children":["Cypher","L.","N."]}
single column, mult...
Possible Results (II)
multiple columns, single row!
{"user": "Andres", "friends": ["Peter","Michael"]}
multiple columns, m...
Implementation
Implementation - Init
Implementation - PUT
Implementation - GET
Usage
Build with mvn clean install dependency:copy-dependencies
Copy files
cypher-rs-2.0-SNAPSHOT.jar opencsv-2.3.jar to pa...
Next Steps
• Add streaming
• Rule the world
Upcoming SlideShare
Loading in …5
×

Document Oriented Access to Graphs

2,266 views

Published on

Author: Michael Hunger (http://twitter.com/mesirii)
Graphs are a great data model for many domains and use-cases.
It would be nice if they were accessed in a document oriented manner, projecting graph query results as compound documents and being able to send in documents whose content is then distributed within the graph.
This presentation discusses "cypher-rs" a Neo4j Server extension that allows exactly that by creating http-endpoints for Cypher queries, which consume and return JSON documents. We look into the general concepts, usage and implementation details.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,266
On SlideShare
0
From Embeds
0
Number of Embeds
30
Actions
Shares
0
Downloads
33
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Document Oriented Access to Graphs

  1. 1. Document oriented access to a graph database Using a Neo4j Server Extension Michael Hunger - @mesirii http://github.com/jexp/cypher-rs
  2. 2. Graphs
  3. 3. Graphs are great • for modeling highly connected domains • finding patterns to answer questions • high performance traversals
  4. 4. Graphs are great
  5. 5. Graphs suck • for compact access patterns • use-case specific views • easy integration in modern webapps
  6. 6. Graphs suck
  7. 7. Documents
  8. 8. Documents are great • for everything that eats JSON • especially modern JavaScript based webapps • as dedicated projections of a domain • compact representation
  9. 9. Documents are great { name:"Michael", age:39, children:[„Selina“,“Rana“,"Selma"], address: { street: „Holbeinstr“, city: „Dresden“} hobbies: [„Coding“,„Buchbar“,“MUD MorgenGrauen“] blog: „http://jexp.de/blog“ }
  10. 10. Documents suck • for different projections besides the main use-case • for connected data • for cross-document linking • for less redundancy / duplication
  11. 11. Documents suck { name:"Michael", age:39, children:[„Selina“,“Rana“,"Selma"], address: { street: „Holbeinstr“, city: „Dresden“} hobbies: [„Coding“,„Buchbar“,“MUD MorgenGrauen“] blog: „http://jexp.de/blog“ } „Show people by hobby“
  12. 12. Documents suck { _id: 1, name:“Michael“, works_at: dbref:2 } { _id: 2, name:“Neo Technology“, employees: [dbref:1] } „Link Employees to Companies“
  13. 13. What can we do? • Use a document oriented access layer for a graph database • Use graph queries whose results project into documents • Make them easily accessible
  14. 14. How can we do that? • Use Cypher in Neo4j 2.0 • Support for literal maps • Parameters, including maps
  15. 15. Cypher Maps
  16. 16. Cypher & Maps - Results MATCH (n:User) WHERE n.name={name} RETURN n // returns a map of the node’s properties RETURN {id: id(n), labels: labels(n), data : n}
  17. 17. Cypher & Maps - Results (II) MATCH (n:User)-[:PARENT_OF]->(child) WHERE n.name={name} RETURN {name:n.name, children:collect(child.name)}
  18. 18. Cypher & Maps - Params CREATE (u:User { name: {p}.name, age: {p}.age}) RETURN u CREATE (u:User {params}) RETURN u
  19. 19. Some Questions
  20. 20. How can we do that? • Create a RESTful API to • Provide endpoints that represent on Cypher queries • Use GET, POST with parameters to execute those endpoints • Return only JSON documents or lists of those
  21. 21. How do we implement it? • Add a Neo4j-Server-Extension • Jersey JAX-RS • Save queries in graph properties • Execute queries for reads on GET • Execute queries for reads and writes on POST • Support JSON and CSV as payload • Batch transactional write operations
  22. 22. What does it look like?
  23. 23. What does it look like? • Examples for • Managing endpoints • Querying Endpoints • Writing to Endpoints
  24. 24. Create Endpoint PUT /cypher-rs/users Body: match (n:User) where n.name={name} return n --> 201 Location: /cypher-rs/users PUT /cypher-rs/create-user Body: create (n:Node {name:{name},age:{age}}) --> 201 Location: /cypher-rs/create-user
  25. 25. GET, POST - Reads
  26. 26. GET Request GET /cypher-rs/users?name=Andres --> 200 {"name":"Andres", "age":21,"children":["Cypher","L.","N."]} GET /cypher-rs/users?name=NotExists --> 204
  27. 27. POST Request - Read POST /cypher-rs/users Content-type: application/json Body: {"name":"Andres"} --> 200 {"name":"Andres","age":21, "children":["Cypher","L.","N."]}
  28. 28. POST Request - Read (II) POST /cypher-rs/users Content-type: application/json Body: [{"name":"Andres"},{"name":"Peter"},{"name":"NotExists"}] ! --> 200 [{"name":"Andres","age":21,"children":["Cypher","L.","N."]}, {"name":"Peter" ,“age“:32,"children":["Neo4j","O.","K."]}, null]
  29. 29. POST - Write
  30. 30. POST Request - Write JSON POST /cypher-rs/create-user Content-type: application/json Body: {"name":"Andres","age":21} --> 201
  31. 31. POST Request - Write JSON (II) POST /cypher-rs/create-user Content-type: application/json Body: [{"name":"Andres","age":21}, {"name":"Peter", "age":40}, --> 201
  32. 32. POST Request - Write CSV (III) POST /cypher-rs/create-user[?batch=20000&delim=,] Content-type: text/plain Body: name,agenAndres,21nPeter,40 --> 201
  33. 33. More Management
  34. 34. Delete Endpoint DELETE /cypher-rs/users --> 200
  35. 35. List Endpoints GET /cypher-rs --> 200 [„create-users“, „users“]
  36. 36. Inspect Endpoint GET /cypher-rs/users/query --> 200 match (n:User) where n.name={name} return n
  37. 37. Results
  38. 38. Possible Results single column, single row! {"name":"Andres","age":21,"children":["Cypher","L.","N."]} single column, multiple rows! [ {"name":"Andres","age":21,"children":["Cypher","L.","N."]}, {"name":"Peter", "age":40,"children":["Neo4j","O.","K."]} ]
  39. 39. Possible Results (II) multiple columns, single row! {"user": "Andres", "friends": ["Peter","Michael"]} multiple columns, multiple rows! [ {"user": "Andres", "friends": ["Peter","Michael"]}, {"user": "Michael","friends": ["Peter","Andres"]}, {"user": "Peter", "friends": ["Andres","Michael"]} ]
  40. 40. Implementation
  41. 41. Implementation - Init
  42. 42. Implementation - PUT
  43. 43. Implementation - GET
  44. 44. Usage Build with mvn clean install dependency:copy-dependencies Copy files cypher-rs-2.0-SNAPSHOT.jar opencsv-2.3.jar to path/to/server/plugins Add this line to path/to/server/conf/neo4j-server.properties org.neo4j.server.thirdparty_jaxrs_classes=org.neo4j.cypher_rs=/cypher-rs Restart
  45. 45. Next Steps • Add streaming • Rule the world

×