GitXplorerGitXplorer
P

graphs

public
6 stars
1 forks
0 issues

Commits

List of commits on branch master.
Unverified
cadbd0eb4645f3c19ff28d912be2edc2512a5cc9

dont upload config to git

committed 5 years ago
Unverified
33cb9357a69c92a6e36b62785bbe20ca118b877a

updaate notebooks

PProteusiq committed 5 years ago
Unverified
fcc70c2f3eb759fbbcb705bacfc7c04d6c689ec1

switch of loging

PProteusiq committed 5 years ago
Unverified
c51fff5586f6c9f284ab2bae9eed742ed1535db3

moved from Neo4j 4.0.1 to 3.5.14 due to plugins

PProteusiq committed 5 years ago
Unverified
23a5d3d32b47f0d53f15e8c5d982079986435c7d

added py2neo

PProteusiq committed 5 years ago
Unverified
90d4339b0e37dfbf04f2db815fc29c0adca1ee6d

minor changes

PProteusiq committed 5 years ago

README

The README file for this repository.

Neo4j & Python

Working with Graphs using Neo4j and Python: Cypher + Graphene + Neomodel = <3

neo4j python

How to Run

Everything is ready to run with a single command after repository cloning. Thanks to docker-compose, we can spin up Jupyter Lab and Neo4j services in no time.

git clone https://github.com/Proteusiq/graphs.git
cd graphs
docker-compose up

To start only Neo4J service execute: docker-compose up neo4j

To shutdown, docker-compose down. We can add -v at the end of the command to remove also volumes, the datasets.

Docker-compose will log a link and token to Jupyter Lab. You can also get the link and token with docker container logs jupyter_lab. To connect to Neo4j, head to localhost:7474 and login in Neo4j browser. The connection url is bolt://localhost:7687. Login username and password is disabled for development, you can set them back on docker-compose file, default username:neo4j and password:test.

Hurrah, you made it. Try out the test.ipynb to get the joy of Python and Neo4j.

Settings

The docker-compose comes with default settings that can be overide. Example, the Jupyter Lab user is danpra. If you want to set your own user, edit the docker-compose.yml

Connection url in Jupyter Lab is bolt://neo4j:test@neo4j:7687 as neo4j is the name of our service in docker-compose.yml.

Simple Family Graph: Taste of Cypher & Neo4j

Cypher is the Python of query languages. It is beautiful, intuitive and simple. To show you it power, let's create a simple dataset and start asking it, yes our dataset, questions.

Create Graph Data Query

Let's build a simple dataset

// Creating the graph: N.B: Enable multi statement query editor on your settings
//Create Person and Location 

//Neo4j 3.X

MERGE (:Person {name:"Prayson",age:34, description:"The Matrix's Neo"})
MERGE (:Person {name:"Lea", age:32, description:"The awesome"})
MERGE (:Person {name:"Eloise",age:8, description:"The dancer"})
MERGE (:Person {name:"Nora",age:5, description:"The wise"})
MERGE (:Person {name:"Mario",age:3, description:"The Jumper"})
MERGE (:Location {address:"Gurrevej 48"}); 

// Neo4j 4.x
MERGE (:Person {name:"Prayson",age:34, description:"The Matrix's Neo"}),
      (:Person {name:"Lea", age:32, description:"The awesome"}),
      (:Person {name:"Eloise",age:8, description:"The dancer"}),
      (:Person {name:"Nora",age:5, description:"The wise"}),
      (:Person {name:"Mario",age:3, description:"The Jumper"}),
      (:Location {address:"Gurrevej 48"});



//Add p person relationship to location l
MATCH (person:Person),(location:Location {address:"Gurrevej 48"})
WHERE person.name in ['Prayson','Mario', 'Nora','Eloise', 'Lea']
MERGE (person)-[:LIVES_IN]->(location);

// Add marriage
MATCH (p:Person {name:"Lea"}),(o:Person {name:"Prayson"})
MERGE (p)<-[:MARRIED_TO]-(o)<-[:MARRIED_TO]-(p);

// Add childrens
MATCH (p:Person), (o:Person)
WHERE p.name = "Prayson" and o.name IN ["Eloise","Nora","Mario"]
MERGE (p)<-[:CHILD_OF]-(o);

MATCH (p:Person), (o:Person)
WHERE p.name ="Lea" and o.name IN ["Eloise","Nora","Mario"]
MERGE (p)<-[:CHILD_OF]-(o);

Show graph:

MATCH (n) RETURN n LIMIT 6

neo4j python

Who is Prayson?:

Query

query for 'Who is Prayson?'

MATCH (p:Person)
WHERE p.name = "Prayson"
RETURN p.description AS `Who is Prayson?`

// OR
MATCH (p:Person {name: "Prayson"})
RETURN p.description AS `Who is Prayson?`

neo4j python

What are the names and age of children leaving in Gurrevej 48 under 18 years old?:

Query

query for 'people leaving in Gurrevej 48 under 18 years old?'

MATCH (under_age:Person),(location:Location)
WHERE under_age.age < 18 and location.address="Gurrevej 48"
RETURN under_age.name AS `Children`, under_age.age AS `Age`

neo4j python

Who lives in Gurrevej 48?:

Query

show, 'Who lives in Gurrevej 48?'

MATCH (p:Person)-[:LIVES_IN]->(l:Location)
WHERE l.address = "Gurrevej 48"
RETURN collect(p.name) AS `Who lives in Gurrevej 48?`

neo4j python

How many children does Prayson have?:

Query

show, 'How many children does Prayson have?'

MATCH (child:Person)-[:CHILD_OF]->(parent:Person)
WHERE parent.name = "Prayson"
RETURN count(child) AS `How many children does Prayson have?`

neo4j python

Power of Cypher over SQL: GraphDB > RelationalDB

So far, we could have performed the queries above with SQL in tabular data. Let's gear up. We know that in real world, relationship are more richer and wider. Let's introduce more relationships.

Getting Large

show, 'How many children does Prayson have?'

//Add more members: My dad, brothers, nephew, and niece

//Neo4j 3.x

MERGE (:Person {name:"Wilfred", age:59, description:"Babu"})
MERGE (:Person {name:"Eric", age:35, description: "First blood"})
MERGE (:Person {name:"Jimmy", age:29, description: "Quantum MD"})
MERGE (:Person {name:"Trace", age:10})
MERGE (:Person {name:"Trisher", age:3});


//Neo4j 4.x
MERGE (:Person {name:"Wilfred", age:59, description:"Babu"}),
      (:Person {name:"Eric", age:35, description: "First blood"}),
      (:Person {name:"Jimmy", age:29, description: "Quantum MD"}),
      (:Person {name:"Trace", age:10}),
      (:Person {name:"Trisher", age:3});

//Add relationship
MATCH (parent:Person), (child:Person)
WHERE parent.name ="Wilfred" and child.name IN ["Eric","Prayson","Jimmy"]
MERGE (parent)<-[:CHILD_OF]-(child)

MATCH (parent:Person), (child:Person)
WHERE parent.name ="Eric" and child.name IN ["Trace","Trisher"]
MERGE (parent)<-[:CHILD_OF]-(child)

//Did not include my mother to keep things simple

extend relation

Cypher > SQL

The power of Cypher comes in query relationships. Imagine we wanted to know the names of Wilfred grandchildren. In SQL, you will have to perform a number of table joins to achieve these. The farther the link, the more joins you will have. With Cypher, two lines of code is all you need.

Two lines of Code

MATCH (grand_child:Person)-[:CHILD_OF*2]->(babu:Person {name: "Wilfred"})
RETURN collect(grand_child.name) AS `Wilfred's grand children are:`

extend relation

There is more. We can ask: What is the shortest child-of path relationship between Mario and Jimmy?

Query

MATCH (mario:Person { name: 'Mario' }),(jimmy:Person { name: 'Jimmy' }),
      path = shortestPath((mario)-[:CHILD_OF*]-(jimmy))
RETURN path

extend relation

Information

Remember: You need to rebuild the services with docker-compose up --build for any new changes in requirements.txt, yml or Dockerfile to take effect.

NOTE If using Neo4j 4.x, mount neomodel to notebook as the current neomodel does not support Neo4J 4.X. Until fixed, this is a temporary hack-solution.

TODO:

  • [ ] Create graphene examples
  • [ ] Add FastAPI to server GraphQL with graphene
  • [ ] Add a second docker-compose with FastAPI image

About Version and Neo4j Plugins

I have pinned Neo4j to version 3.5.14 and downloaded Apoc 3.5 and Algo 3.5 See Apoc Github and Algo Github for more information.