For detailed documentation on the concepts use here, see Section 19.3, “Indexes” and Section 19.5, “Traversals”.
This example shows you how to get started building something like a simple invoice tracking application with Neo4j.
We start out by importing Neo4j, and creating some meta data that we will use to organize our actual data with.
from neo4j import GraphDatabase, INCOMING, Evaluation # Create a database db = GraphDatabase(folder_to_put_db_in) # All write operations happen in a transaction with db.transaction: # A node to connect customers to customers = db.node() # A node to connect invoices to invoices = db.node() # Connected to the reference node, so # that we can always find them. db.reference_node.CUSTOMERS(customers) db.reference_node.INVOICES(invoices) # An index, helps us rapidly look up customers customer_idx = db.node.indexes.create('customers')
Then we define some domain logic that we want our application to be able to perform. Our application has two domain objects, Customers and Invoices. Let’s create methods to add new customers and invoices.
def create_customer(name): with db.transaction: customer = db.node(name=name) customer.INSTANCE_OF(customers) # Index the customer by name customer_idx['name'][name] = customer return customer def create_invoice(customer, amount): with db.transaction: invoice = db.node(amount=amount) invoice.INSTANCE_OF(invoices) invoice.RECIPIENT(customer) return customer
In the customer case, we create a new node to represent the customer and connect it to the customers node. This helps us find customers later on, as well as determine if a given node is a customer.
We also index the name of the customer, to allow for quickly finding customers by name.
In the invoice case, we do the same, except no indexing. We also connect each new invoice to the customer it was sent to, using a relationship of type SENT_TO
.
Next, we want to be able to retrieve customers and invoices that we have added. Because we are indexing customer names, finding them is quite simple.
def get_customer(name): return customer_idx['name'][name].single
Lets say we also like to do something like finding all invoices for a given customer that are above some given amount. This could be done by writing a traversal, like this:
def get_invoices_with_amount_over(customer, min_sum): def evaluator(path): node = path.end if node.has_key('amount') and node['amount'] > min_sum: return Evaluation.INCLUDE_AND_CONTINUE return Evaluation.EXCLUDE_AND_CONTINUE return db.traversal()\ .relationships('RECIPIENT', INCOMING)\ .evaluator(evaluator)\ .traverse(customer)\ .nodes
Putting it all together, we can create customers and invoices, and use the search methods we wrote to find them.
for name in ['Acme Inc.', 'Example Ltd.']: create_customer(name) # Loop through customers for relationship in customers.INSTANCE_OF: customer = relationship.start for i in range(1,12): create_invoice(customer, 100 * i) # Finding large invoices large_invoices = get_invoices_with_amount_over(get_customer('Acme Inc.'), 500) # Getting all invoices per customer: for relationship in get_customer('Acme Inc.').RECIPIENT.incoming: invoice = relationship.start
Copyright © 2012 Neo Technology