Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
Neo4j and Python: Playing with graph data - PyCon India 2014 Talk.
Next
Download to read offline and view in fullscreen.

18

Share

Introduction to py2neo

Download to read offline

An introduction to the python library py2neo, used for building applications which use the Neo4j graph database.

Introduction to py2neo

  1. 1. Introducing py2neo nigel@nigelsmall.name py2neo.org @technige @py2neo
  2. 2. Me...
  3. 3. Where does py2neo fit in? (your app) py2neo GET /db/data/ 200 OK REST Server Neo4j
  4. 4. Coming Up... ● Connecting & Creating ● Property Containers ● Indexes & Uniqueness ● Cypher & Geoff ● Installation ● Future Plans
  5. 5. Connecting & Creating
  6. 6. Default Connections >>> from py2neo import neo4j >>> graph_db = neo4j.GraphDatabaseService() default connection is made to <http://localhost:7474/db/data/>
  7. 7. Custom Connections >>> from py2neo import neo4j >>> uri = "http://otherserv:9999/db/data/" >>> graph_db = neo4j.GraphDatabaseService(uri) >>> graph_db.neo4j_version (1, 8, u'M04', 1, u'g892e348')
  8. 8. A few simple methods... >>> graph_db.get_node(0) Node('http://localhost:7474/db/data/node/0') >>> graph_db.get_reference_node() Node('http://localhost:7474/db/data/node/0') >>> graph_db.get_node_count() 1 >>> graph_db.get_relationship_count() 0
  9. 9. Sample data: a family tree m (1947) Phil (1921) Liz (1926) Chaz (1948) Anne (1950) Andy (1960) Ed (1964) All characters appearing in this work are fictitious. Any resemblance to real persons, living or dead, is purely coincidental.
  10. 10. list of nodes create nodes = graph_db.create( Phil Liz {"name": "Phil", "born": 1921}, {"name": "Liz", "born": 1926}, {"name": "Chaz", "born": 1948}, {"name": "Anne", "born": 1950}, Chaz Anne {"name": "Andy", "born": 1960}, {"name": "Ed", "born": 1964}, ) Andy Ed
  11. 11. list of relationships create MARRIED rels = graph_db.create( Phil Liz (phil, "MARRIED", liz), (chaz, "FATHER", phil), FATHER MOTHER (chaz, "MOTHER", liz), Chaz ) node must already exist
  12. 12. create family = graph_db.create( {"name": "Phil", "born": 1921}, {"name": "Liz", "born": 1926}, {"name": "Chaz", "born": 1948}, {"name": "Anne", "born": 1950}, {"name": "Andy", "born": 1960}, {"name": "Ed", "born": 1964}, (0, "MARRIED", 1, {"year": 1947, "place": "London"}), (2, "FATHER", 0), (3, "FATHER", 0), (4, "FATHER", 0), (5, "FATHER", 0), (2, "MOTHER", 1), (3, "MOTHER", 1), (4, "MOTHER", 1), (5, "MOTHER", 1), )
  13. 13. list of nodes and relationships create family = graph_db.create( {"name": "Phil", "born": 1921}, {"name": "Liz", "born": 1926}, {"name": "Chaz", "born": 1948}, {"name": "Anne", "born": 1950}, {"name": "Andy", "born": 1960}, {"name": "Ed", "born": 1964}, (0, "MARRIED", 1, {"year": 1947, "place": "London"}), (2, "FATHER", 0), (3, "FATHER", 0), relationship (4, "FATHER", 0), (5, "FATHER", 0), properties (2, "MOTHER", 1), (3, "MOTHER", 1), (4, "MOTHER", 1), (5, "MOTHER", 1), ) node defined in same batch nodes, rels = family[0:6], family[6:] phil, liz, chaz, anne, andy, ed = nodes
  14. 14. Property Containers
  15. 15. neo4j.PropertyContainer PropertyContainer Node Relationship
  16. 16. PropertyContainers implement many of the container methods defined by the Python standard <http://docs.python.org/reference/datamodel.html#emulating-container-types>
  17. 17. neo4j.PropertyContainer set property # update properties liz["star_sign"] = "Taurus" # query properties get property test property for node in nodes: containment name = node["name"] if "star_sign" in node: print name + " is a node["star_sign"] else: print name + " doesn't believe in horoscopes"
  18. 18. neo4j.Node PropertyContainer Node Relationship
  19. 19. Relationships and Related Nodes Chaz parental_rels = liz.get_relationships( Liz neo4j.Direction.INCOMING, "MOTHER" Anne ) Chaz parental_rels = liz.get_relationships_with( Liz chaz, neo4j.Direction.INCOMING, "MOTHER" Anne ) Chaz children = liz.get_related_nodes( Liz neo4j.Direction.INCOMING, "MOTHER" Anne )
  20. 20. Relationships and Related Nodes >>> liz.has_relationship(neo4j.Direction.BOTH, "MARRIED") True >>> anne.is_related_to(phil, neo4j.Direction.OUTGOING, "FATHER") True >>> ed.is_related_to(andy, neo4j.Direction.BOTH, "BROTHER") False could also specify multiple types
  21. 21. neo4j.Relationship PropertyContainer Node Relationship
  22. 22. neo4j.Relationship >>> rels[0].start_node Node('http://localhost:7474/db/data/node/1') >>> rels[0].end_node Node('http://localhost:7474/db/data/node/2') >>> rels[0].type 'MARRIED'
  23. 23. More sample data: a second tree m George (1895) Betty (1900) Liz (1926) Maggie (1930)
  24. 24. m George (1895) Betty (1900) Liz (1926) Maggie (1930) m (1947) Phil (1921) Liz (1926) Chaz (1948) Anne (1950) Andy (1960) Ed (1964)
  25. 25. m George (1895) Betty (1900) same person Liz (1926) Maggie (1930) m (1947) Phil (1921) Liz (1926) Chaz (1948) Anne (1950) Andy (1960) Ed (1964)
  26. 26. How can we avoid duplicate nodes?
  27. 27. Indexes
  28. 28. Indexing the first family... >>> people = graph_db.get_or_create_index(neo4j.Node, "People") >>> for node in nodes: ... people.add("name", node["name"], node) >>> people.get("name", "Liz") [Node('http://localhost:7474/db/data/node/2')] list of matching entities
  29. 29. ...and the second >>> new_props = [ ... {"name": "George", "born": 1895}, ... {"name": "Betty", "born": 1900}, ... {"name": "Liz", "born": 1926}, ... {"name": "Maggie", "born": 1930}, ... ] >>> george, betty, liz, maggie = [ ... people.get_or_create("name", prop["name"], prop) ... for prop in new_props same node ... ] as before >>> people.get("name", "Liz") [Node('http://localhost:7474/db/data/node/2')]
  30. 30. A Quick Query >>> people.query("name:*e*") [Node('http://localhost:7474/db/data/node/4'), Node('http://localhost:7474/db/data/node/7'), Node('http://localhost:7474/db/data/node/8'), Node('http://localhost:7474/db/data/node/9')] People George name Andy name Anne Maggie name Betty name Chaz name Ed name George Anne name Liz name Maggie Betty name Phil
  31. 31. We've added the nodes... what about the relationships?
  32. 32. Cypher & Geoff
  33. 33. Cypher RELATE START a=node(1), b=node(2) RELATE (a)-[ab:KNOWS]->(b) RETURN ab
  34. 34. Cypher RELATE a b RELATE a b a b RELATE a b ! a b RELATE
  35. 35. relate new_rels = graph_db.relate( (george, "MARRIED", betty), (liz, "FATHER", george), (maggie, "FATHER", george), (liz, "MOTHER", betty), (maggie, "MOTHER", betty), George MARRIED Betty ) FATHER FATHER MOTHER MOTHER Liz Maggie
  36. 36. For relationships, relate can be seen as an idempotent alternative to create
  37. 37. cypher.execute >>> from py2neo import cypher >>> query = "START q=node(1) RETURN q" >>> data, metadata = cypher.execute(graph_db, query) >>> for row in data: ... q = row[0] ... print q first column
  38. 38. cypher.execute >>> from py2neo import cypher >>> query = "START q=node(1) RETURN q" >>> data, metadata = cypher.execute(graph_db, query) available only after all rows received >>> for row in data: ... q = row[0] ... print q first column
  39. 39. cypher.execute query = "START q=node(1) RETURN q" executed once per row as each def print_row(row): row is received q = row[0] print row cypher.execute(graph_db, query, row_handler=print_row)
  40. 40. Command Line Cypher elgin@forge:~% cypher "start a=node(1) match (a)-[:MARRIED]->(b) return a, b" +------------------------------------------------------------------+ | a | b | +------------------------------------------------------------------+ | (1) {"name":"Phil","born":1921} | (2) {"name":"Liz","born":1926} | +------------------------------------------------------------------+ elgin@forge:~% cypher -f csv "start a=node(1) match (a)-[ab:MARRIED]->(b) return a, ab, b" "a","ab","b" "(1)","(1)-[0:MARRIED]->(2)","(2)" elgin@forge:~% cypher -f json "start a=node(1) match (a)-[ab:MARRIED]->(b) return a, ab, b" [ {"a": "(1)", "ab": "(1)-[0:MARRIED]->(2)", "b": "(2)"} ] elgin@forge:~% cypher -f geoff "start a=node(1) match (a)-[ab:MARRIED]->(b) return a, ab, b" (1) {"name": "Phil", "born": 1921} (2) {"name": "Liz", "born": 1926} (1)-[0:MARRIED]->(2) {"year": 1947, "place": "London"}
  41. 41. Geoff is to graph data as CSV is to tabular data <http://geoff.nigelsmall.net/>
  42. 42. elgin@forge:~% cypher -f geoff "start n=node(*), r=rel(*) return n, r" (0) {} (1) {"born": 1921, "name": "Phil", "family": "Windsor"} (2) {"born": 1926, "star_sign": "Taurus", "family": "Windsor", "name": "Liz"} (3) {"born": 1948, "name": "Chaz", "family": "Windsor"} (4) {"born": 1950, "name": "Anne", "family": "Windsor"} (5) {"born": 1960, "name": "Andy", "family": "Windsor"} (6) {"born": 1964, "name": "Ed", "family": "Windsor"} (7) {"born": 1895, "name": "George"} (8) {"born": 1900, "name": "Betty"} (9) {"born": 1930, "name": "Maggie"} (1)-[0:MARRIED]->(2) {"place": "London", "year": 1947} (3)-[1:FATHER]->(1) {} (4)-[2:FATHER]->(1) {} (5)-[3:FATHER]->(1) {} (6)-[4:FATHER]->(1) {} (3)-[5:MOTHER]->(2) {} (4)-[6:MOTHER]->(2) {} (5)-[7:MOTHER]->(2) {} (6)-[8:MOTHER]->(2) {} (7)-[9:MARRIED]->(8) {} (2)-[10:FATHER]->(7) {} (9)-[11:FATHER]->(7) {} (2)-[12:MOTHER]->(8) {} (9)-[13:MOTHER]->(8) {}
  43. 43. Neo4j Console
  44. 44. Installation
  45. 45. Requirements ● Python 2.6+ <http://python.org/> ● Tornado 2.2.1 <http://www.tornadoweb.org/> ● Neo4j 1.6+ <http://neo4j.org/>
  46. 46. Installation <http://pypi.python.org/pypi/py2neo> elgin@forge:~% sudo pip install py2neo elgin@forge:~% sudo pip install --upgrade py2neo
  47. 47. Source Code <https://github.com/nigelsmall/py2neo> elgin@forge:~% git clone git@github.com:nigelsmall/py2neo.git
  48. 48. Future Plans ● Fast HTTP ● Multi-threading support ● Python 3 ● Command line tools ● Property caching ● Test harness for multiple Neo4j versions ● New methods, e.g. get_paths_to
  49. 49. EOF nigel@nigelsmall.name py2neo.org @technige @py2neo
  • YuanfeiFan

    Dec. 22, 2020
  • YesmineBellalah

    Mar. 28, 2018
  • shigeosuwa

    Mar. 10, 2018
  • MartinHoffmann2

    Feb. 18, 2018
  • IgorPereira31

    Feb. 16, 2018
  • StefanoBragaglia

    Dec. 14, 2016
  • Kafrou

    Nov. 24, 2016
  • bbkingtw

    Nov. 19, 2016
  • mrpease1

    Dec. 24, 2015
  • yifanxie

    Jul. 31, 2015
  • shiraco

    Feb. 8, 2015
  • aleksandrsytar

    Dec. 21, 2014
  • evandrix

    Jun. 10, 2014
  • airabbit

    Mar. 27, 2014
  • ishafizan

    Feb. 6, 2014
  • ssuser5ef4c0

    Dec. 29, 2013
  • Mice73

    Nov. 23, 2013
  • GibsonYang

    Nov. 29, 2012

An introduction to the python library py2neo, used for building applications which use the Neo4j graph database.

Views

Total views

19,075

On Slideshare

0

From embeds

0

Number of embeds

2,728

Actions

Downloads

324

Shares

0

Comments

0

Likes

18

×