Use the Neo4j database tutorial in Python, pythonneo4j
A quick REST example
First, let's look at some basic knowledge. Without service APIs, Neo4j cannot support other languages. This interface provides a set of RESTful Web Services Based on the JSON Message format and a comprehensive discovery mechanism. The fastest and easiest way to use this interface is by using cURL:
$ curl http://localhost:7474/db/data/{ "extensions" : { }, "node" : "http://localhost:7474/db/data/node", "node_index" : "http://localhost:7474/db/data/index/node", "relationship_index" : "http://localhost:7474/db/data/index/relationship", "extensions_info" : "http://localhost:7474/db/data/ext", "relationship_types" : "http://localhost:7474/db/data/relationship/types", "batch" : "http://localhost:7474/db/data/batch", "cypher" : "http://localhost:7474/db/data/cypher", "transaction" : "http://localhost:7474/db/data/transaction", "neo4j_version" : "2.0.0-M03"}
The returned JSON object from this endpoint contains a set of resource names and Cypher endpoints that can be found under the URI. Receive sent Cyper requests in the message load and execute these queries, and return results in the HTTP response.
It is precisely this restful API interface that allows existing Neo4j drivers to be created. Py2neo provides simple encapsulation of these REST resources, so that Python application developers can use Neo4j with confidence without considering the underlying client-server protocol.
A simple application
To verify py2neo, we will focus on creating a simple address book management system for storing names and email addresses. We will naturally use nodes to simulate every independent entity, but it is important to remember that Neo4j does not have the concept of type. Types are inferred from the relationships and attributes.
In the diagram below, the nodes are displayed in red and the email addresses are displayed in blue. These are of course purely logical demonstration nodes, but the data itself is no different.
Our application completes two functions: adding new contact information and retrieving the complete list of contacts. To this end, we will create a Person class packaging Py2neoNodeobject, which enables us to implement underlying processing and set aside user-level functions. The ROOT node in is a fixed reference point. We start at this point.
Let's look at the Code directly. The following is a complete small application. This program allows you to add a new name to connect with one or more email addresses and provides a command line tool that easily displays the connection information. Running without parameters is the display mode, and the unique dependency only requires a local unmodified Neo4j instance.
#!/usr/bin/env python# -*- coding: utf-8 -*- from __future__ import print_function import sysfrom py2neo import neo4j, node, rel graph_db = neo4j.GraphDatabaseService() class Person(object): _root = graph_db.get_or_create_indexed_node("reference", "contacts", "root") @classmethod def create(cls, name, *emails): person_node, _ = graph_db.create(node(name=name), rel(cls._root, "PERSON", 0)) for email in emails: graph_db.create(node(email=email), rel(cls._root, "EMAIL", 0), rel(person_node, "EMAIL", 0)) return Person(person_node) @classmethod def get_all(cls): return [Person(person.end_node) for person in cls._root.match("PERSON")] def __init__(self, node): self._node = node def __str__(self): return self.name + "\n" + "\n".join(" <{0}>" .format(email) for email in self.emails) @property def name(self): return self._node["name"] @property def emails(self): return [rel.end_node["email"] for rel in self._node.match("EMAIL")] if __name__ == "__main__": if len(sys.argv) < 2: app = sys.argv[0] print("Usage: {0} add <name> <email> [<email>...]".format(app)) print(" {0} list".format(app)) sys.exit() method = sys.argv[1] if method == "add": print(Person.create(*sys.argv[2:])) elif method == "list": for person in Person.get_all(): print(person) else:print("Unknown command")
The first line of the Py2neo code is on line 1, which is used to create a GraphDatabaseService object. With this, we can access most features of the Neo4j server. You can choose to pass a URI to this constructor. Even if nothing is provided, the default local parameter is used instead. That is to say, the following two rows are completely equal:
graph_db = neo4j.GraphDatabaseService()graph_db = neo4j.GraphDatabaseService("http://localhost:7474/db/data/")
Row 13th introduces the call to get_or_create_indexed_node, which provides a beautiful way to create fixed reference points in a graph. Traditional Neo4j indexes allow nodes and relationships to be accessed through key-value pairs. In this code, we use reference index instances with connected keywords and root values. During the first execution, a new node will be created, and in subsequent execution, this node (that is, root) will be reused (reused ).
In row 3, we saw the recommended node and link abstraction mark, and the create method that accepts and uses node and link abstraction. Any number of abstractions can be passed to this method, and an entity is created in a single batch transformation and returned as a list in the specified order. Abstract nodes are represented by node functions with some attributes. However, the abstract relationship uses the rel function to accept a Start Node, type, and end node. In the context, other nodes, link start and end nodes may be integrated and referenced to other nodes in other batches. In our example, we connect the root node to the newly created person node, otherwise it will be used as project 0 (item 0.
This time, we will see each other in the form of a match and link on lines 3 and 38 [@ Lesus Note: there is a problem with the number of lines of oschina code. Corresponding to rows 28th and 44 in this article]. It tries to use a special set to identify the relationship, and then returns them using list. In these examples, the relationship matches the PERSON relationship, starting from the root node and the e-mail relationship to the given person node. Similar to Cypher, it is used to query scenarios that contain the MATCH keyword.
Finally, it is worth noting that the method for accessing node attributes in the code above is only one simple method. Py2neo overrides the _ getitem _ and _ setitem _ methods of standard python and uses square brackets to easily access any attributes. This can be seen in rows 34th and 38. [@ Lesus Note: corresponding to rows 39th and 44 in this article]
Summary
We did this there (code lines 34 and 38), which shows how it quickly and easily pieces together a Neo4j application outside the JAVA environment, it also shows how Py2neo abstracts a majority of heavy loads through REST APIs. The example here does not solve the uniqueness, although the function provides the UNIQUE index and CypherCREATE UNIQUE statement. Django developers may also want to consider a layer, such as Neomodel, which represents a Djangoesque ORM-style Layer on the top layer of Py2neo.