SlideShare a Scribd company logo
1 of 49
Download to read offline
Introducing


                  py2neo




nigel@nigelsmall.name                 py2neo.org
@technige                              @py2neo
Me...
Where does py2neo fit in?

               (your app)

             py2neo




         GET /db/data/
         200 OK




           REST Server


               Neo4j
Coming Up...

●
    Connecting & Creating
●
    Property Containers
●
    Indexes & Uniqueness
●
    Cypher & Geoff
●
    Installation
●
    Future Plans
Connecting & Creating
Default Connections
>>> from py2neo import neo4j
>>> graph_db = neo4j.GraphDatabaseService()




                      default connection is made to
                     <http://localhost:7474/db/data/>
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')
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
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.
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
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
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),
)
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
Property Containers
neo4j.PropertyContainer


         PropertyContainer




  Node                 Relationship
PropertyContainers
              implement many of the
            container methods defined
              by the Python standard



<http://docs.python.org/reference/datamodel.html#emulating-container-types>
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"
neo4j.Node


       PropertyContainer




Node                 Relationship
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
)
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
neo4j.Relationship


       PropertyContainer




Node                 Relationship
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'
More sample data: a second tree

                        m
        George (1895)       Betty (1900)




          Liz (1926)        Maggie (1930)
m
                                                               George (1895)       Betty (1900)




                                                                 Liz (1926)        Maggie (1930)




                              m
                            (1947)
              Phil (1921)             Liz (1926)




Chaz (1948)   Anne (1950)            Andy (1960)   Ed (1964)
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)
How can we avoid
duplicate nodes?
Indexes
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
...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')]
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
We've added the
nodes... what about
 the relationships?
Cypher & Geoff
Cypher RELATE


START a=node(1), b=node(2)
RELATE (a)-[ab:KNOWS]->(b)
RETURN ab
Cypher RELATE

a   b   RELATE   a       b




a   b   RELATE   a       b




                     !
a   b   RELATE
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
For relationships,
relate can be seen as
   an idempotent
 alternative to create
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
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
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)
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"}
Geoff is to graph data
               as
CSV is to tabular data



  <http://geoff.nigelsmall.net/>
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) {}
Neo4j Console
Installation
Requirements
●
    Python 2.6+ <http://python.org/>
●
    Tornado 2.2.1 <http://www.tornadoweb.org/>
●
    Neo4j 1.6+ <http://neo4j.org/>
Installation
          <http://pypi.python.org/pypi/py2neo>


elgin@forge:~% sudo pip install py2neo

elgin@forge:~% sudo pip install --upgrade py2neo
Source Code
         <https://github.com/nigelsmall/py2neo>


elgin@forge:~% git clone git@github.com:nigelsmall/py2neo.git
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
EOF

nigel@nigelsmall.name     py2neo.org
@technige                  @py2neo

More Related Content

What's hot

ret2dl resolve
ret2dl resolveret2dl resolve
ret2dl resolvesounakano
 
Swagman - Converting Postman Collection to Swagger Build
Swagman - Converting Postman Collection to Swagger BuildSwagman - Converting Postman Collection to Swagger Build
Swagman - Converting Postman Collection to Swagger BuildAjinkya Dubey
 
Randomforestで高次元の変数重要度を見る #japanr LT
 Randomforestで高次元の変数重要度を見る #japanr LT Randomforestで高次元の変数重要度を見る #japanr LT
Randomforestで高次元の変数重要度を見る #japanr LTAkifumi Eguchi
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJSAbul Hasan
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Daniele Pallastrelli
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論MITSUNARI Shigeo
 
Luhn algorithm
Luhn algorithm Luhn algorithm
Luhn algorithm Al Vas
 
Intro to Github Actions @likecoin
Intro to Github Actions @likecoinIntro to Github Actions @likecoin
Intro to Github Actions @likecoinWilliam Chong
 
Reward Innovation for long-term member satisfaction
Reward Innovation for long-term member satisfactionReward Innovation for long-term member satisfaction
Reward Innovation for long-term member satisfactionJiangwei Pan
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsScott Wlaschin
 
git - eine praktische Einführung
git - eine praktische Einführunggit - eine praktische Einführung
git - eine praktische EinführungMarcel Eichner
 
Access modifiers in Python
Access modifiers in PythonAccess modifiers in Python
Access modifiers in PythonSantosh Verma
 

What's hot (14)

ret2dl resolve
ret2dl resolveret2dl resolve
ret2dl resolve
 
Swagman - Converting Postman Collection to Swagger Build
Swagman - Converting Postman Collection to Swagger BuildSwagman - Converting Postman Collection to Swagger Build
Swagman - Converting Postman Collection to Swagger Build
 
Randomforestで高次元の変数重要度を見る #japanr LT
 Randomforestで高次元の変数重要度を見る #japanr LT Randomforestで高次元の変数重要度を見る #japanr LT
Randomforestで高次元の変数重要度を見る #japanr LT
 
Python程式設計 - 串列資料應用
Python程式設計 - 串列資料應用 Python程式設計 - 串列資料應用
Python程式設計 - 串列資料應用
 
Git & GitHub for Beginners
Git & GitHub for BeginnersGit & GitHub for Beginners
Git & GitHub for Beginners
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++Going native with less coupling: Dependency Injection in C++
Going native with less coupling: Dependency Injection in C++
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
 
Luhn algorithm
Luhn algorithm Luhn algorithm
Luhn algorithm
 
Intro to Github Actions @likecoin
Intro to Github Actions @likecoinIntro to Github Actions @likecoin
Intro to Github Actions @likecoin
 
Reward Innovation for long-term member satisfaction
Reward Innovation for long-term member satisfactionReward Innovation for long-term member satisfaction
Reward Innovation for long-term member satisfaction
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of tests
 
git - eine praktische Einführung
git - eine praktische Einführunggit - eine praktische Einführung
git - eine praktische Einführung
 
Access modifiers in Python
Access modifiers in PythonAccess modifiers in Python
Access modifiers in Python
 

Viewers also liked

Django and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks assDjango and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks assTobias Lindaaker
 
Word Puzzles with Neo4j and Py2neo
Word Puzzles with Neo4j and Py2neoWord Puzzles with Neo4j and Py2neo
Word Puzzles with Neo4j and Py2neoGrant Paton-Simpson
 
Persistent graphs in Python with Neo4j
Persistent graphs in Python with Neo4jPersistent graphs in Python with Neo4j
Persistent graphs in Python with Neo4jTobias Lindaaker
 
Odessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonOdessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonMax Klymyshyn
 
Creative Data Analysis with Python
Creative Data Analysis with PythonCreative Data Analysis with Python
Creative Data Analysis with PythonGrant Paton-Simpson
 
Natural Language Processing and Graph Databases in Lumify
Natural Language Processing and Graph Databases in LumifyNatural Language Processing and Graph Databases in Lumify
Natural Language Processing and Graph Databases in LumifyCharlie Greenbacker
 
Round pegs and square holes
Round pegs and square holesRound pegs and square holes
Round pegs and square holesDaniel Greenfeld
 
A quick review of Python and Graph Databases
A quick review of Python and Graph DatabasesA quick review of Python and Graph Databases
A quick review of Python and Graph DatabasesNicholas Crouch
 
An example graph visualization with processing
An example graph visualization with processingAn example graph visualization with processing
An example graph visualization with processingMax De Marzi
 
Importing Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflowImporting Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflowNeo4j
 
Building social network with Neo4j and Python
Building social network with Neo4j and PythonBuilding social network with Neo4j and Python
Building social network with Neo4j and PythonAndrii Soldatenko
 
An overview of Neo4j Internals
An overview of Neo4j InternalsAn overview of Neo4j Internals
An overview of Neo4j InternalsTobias Lindaaker
 
Natural Language Processing with Graph Databases and Neo4j
Natural Language Processing with Graph Databases and Neo4jNatural Language Processing with Graph Databases and Neo4j
Natural Language Processing with Graph Databases and Neo4jWilliam Lyon
 
Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...
Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...
Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...Kavita Ganesan
 

Viewers also liked (15)

Django and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks assDjango and Neo4j - Domain modeling that kicks ass
Django and Neo4j - Domain modeling that kicks ass
 
Word Puzzles with Neo4j and Py2neo
Word Puzzles with Neo4j and Py2neoWord Puzzles with Neo4j and Py2neo
Word Puzzles with Neo4j and Py2neo
 
Py2neo 1.6
Py2neo 1.6Py2neo 1.6
Py2neo 1.6
 
Persistent graphs in Python with Neo4j
Persistent graphs in Python with Neo4jPersistent graphs in Python with Neo4j
Persistent graphs in Python with Neo4j
 
Odessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and PythonOdessapy2013 - Graph databases and Python
Odessapy2013 - Graph databases and Python
 
Creative Data Analysis with Python
Creative Data Analysis with PythonCreative Data Analysis with Python
Creative Data Analysis with Python
 
Natural Language Processing and Graph Databases in Lumify
Natural Language Processing and Graph Databases in LumifyNatural Language Processing and Graph Databases in Lumify
Natural Language Processing and Graph Databases in Lumify
 
Round pegs and square holes
Round pegs and square holesRound pegs and square holes
Round pegs and square holes
 
A quick review of Python and Graph Databases
A quick review of Python and Graph DatabasesA quick review of Python and Graph Databases
A quick review of Python and Graph Databases
 
An example graph visualization with processing
An example graph visualization with processingAn example graph visualization with processing
An example graph visualization with processing
 
Importing Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflowImporting Data into Neo4j quickly and easily - StackOverflow
Importing Data into Neo4j quickly and easily - StackOverflow
 
Building social network with Neo4j and Python
Building social network with Neo4j and PythonBuilding social network with Neo4j and Python
Building social network with Neo4j and Python
 
An overview of Neo4j Internals
An overview of Neo4j InternalsAn overview of Neo4j Internals
An overview of Neo4j Internals
 
Natural Language Processing with Graph Databases and Neo4j
Natural Language Processing with Graph Databases and Neo4jNatural Language Processing with Graph Databases and Neo4j
Natural Language Processing with Graph Databases and Neo4j
 
Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...
Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...
Opinosis Presentation @ Coling 2010: Opinosis - A Graph Based Approach to Abs...
 

Recently uploaded

Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

py2neo: A Python Graph Database Connector/TITLE

  • 1. Introducing py2neo nigel@nigelsmall.name py2neo.org @technige @py2neo
  • 3. Where does py2neo fit in? (your app) py2neo GET /db/data/ 200 OK REST Server Neo4j
  • 4. Coming Up... ● Connecting & Creating ● Property Containers ● Indexes & Uniqueness ● Cypher & Geoff ● Installation ● Future Plans
  • 6. Default Connections >>> from py2neo import neo4j >>> graph_db = neo4j.GraphDatabaseService() default connection is made to <http://localhost:7474/db/data/>
  • 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. 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. 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. 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. 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. 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. 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
  • 15. neo4j.PropertyContainer PropertyContainer Node Relationship
  • 16. PropertyContainers implement many of the container methods defined by the Python standard <http://docs.python.org/reference/datamodel.html#emulating-container-types>
  • 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. neo4j.Node PropertyContainer Node Relationship
  • 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. 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. neo4j.Relationship PropertyContainer Node Relationship
  • 23. More sample data: a second tree m George (1895) Betty (1900) Liz (1926) Maggie (1930)
  • 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. 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. How can we avoid duplicate nodes?
  • 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. ...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. 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. We've added the nodes... what about the relationships?
  • 33. Cypher RELATE START a=node(1), b=node(2) RELATE (a)-[ab:KNOWS]->(b) RETURN ab
  • 34. Cypher RELATE a b RELATE a b a b RELATE a b ! a b RELATE
  • 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. For relationships, relate can be seen as an idempotent alternative to create
  • 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. 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. 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. 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. Geoff is to graph data as CSV is to tabular data <http://geoff.nigelsmall.net/>
  • 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) {}
  • 45. Requirements ● Python 2.6+ <http://python.org/> ● Tornado 2.2.1 <http://www.tornadoweb.org/> ● Neo4j 1.6+ <http://neo4j.org/>
  • 46. Installation <http://pypi.python.org/pypi/py2neo> elgin@forge:~% sudo pip install py2neo elgin@forge:~% sudo pip install --upgrade py2neo
  • 47. Source Code <https://github.com/nigelsmall/py2neo> elgin@forge:~% git clone git@github.com:nigelsmall/py2neo.git
  • 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. EOF nigel@nigelsmall.name py2neo.org @technige @py2neo