Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
399 lines (272 sloc) 13.5 KB

Examples

Below we have given examples of the most common operations in Neo4clj.

Table of Contents

Basic requirements

To make the client available and setup a connection run the following:

(require '[neo4clj.client :as client])

(def conn (client/connect "bolt://localhost:7687"))

Make the Neo4j client and connection available in the client and conn symbols respectively, this is a requirement for the subsequent examples to work.

You might need to adjust the connection parameters to match your setup, see below.

Connect to neo4j server

This section will show you how to connect with or without authentication and how to change some of the basic options for the connection.

Basic connection

(def conn (client/connect "bolt://localhost:7687"))

Authenticated connection

(def conn (client/connect "bolt://localhost:7687" "neo4j" "password"))

Connection with options

(def conn (client/connect "bolt://localhost:7687" {:log {:level :info}}))

This also works on authenticated connections.

(def conn
  (client/connect
    "bolt://localhost:7687"
    "neo4j"
    "password"
    {:log {:level :info}
           :encryption :none}))

In the current version we support the following options:

:log :level [:all :error :warn :info :off] - defaults to :warn
:encryption [:required :none] - defaults to :required"

Disconnect from neo4j server

(client/disconnect conn)

Execute queries

This section shows how to execute raw bolt queries against on a open connection

Execute query without parameters

(client/execute! conn "MATCH (n:Person) RETURN n")

Execute query with parameters

(client/execute! conn "MATCH (n:Person {firstName: $first_name}) RETURN n" {:first_name "Neo"})

Notice that dashes is not allowed in parameter names

Node CRUD

This section shows how to do basic CRUD operations on nodes through Neo4clj convenience functions. To learn more about the Clojure representation of a node please see our representations page

Create a Node

(client/create-node! conn {:ref-id "p"
                           :labels [:person]
                           :props {:first-name "Neo"
                                   :last-name "Anderson"}})

Find nodes in Neo4j

The entry given to find-nodes! is a lookup representation. To learn more about the Clojure lookup representation see our representations page

(client/find-nodes! conn {:ref-id "p"
                          :labels [:person]
                          :props {:first-name "Neo"
                                  :last-name "Anderson"}})

Update and Delete Node

See the section Update and Delete Entity

Relationship CRUD

This section shows how to do basic CRUD operations on relationships through Neo4clj convenience functions. To learn more about the Clojure representation of a relationship please see our representations page

Create a Relationship

The keys from and to are Lookup representations. To learn more about the Clojure representation of a lookup entry please see our representations page

(client/create-relationship! conn {:ref-id "p"
                                   :type :employee
                                   :from {:labels [:person] :props {:first-name "Neo"}}
                                   :to {:id 12}
                                   :props {:position "Developer"}})

Find relationships in Neo4j

To fetch relationships from the Neo4j database, please refer to the section Get Graph

Update and Delete Relationship

See the section Update and Delete Entity

Update and Delete Neo4j Entity

Nodes and relationships are both part of the broader category named "entities" and this section will describe how to update and delete them.

In this section you can find examples on how to update specific parts a Node or Relationship and how to delete them.

Update Node (Labels)

To change the labels of a node we have added two convenience functions. Both the add-labels! and remove-labels! functions takes a lookup representation as second argument. To learn more about the Clojure representation of a lookup entry please see our representations page

Add labels

(client/add-labels! conn {:id 45} [:person :salesman])

Remove labels

(client/remove-labels! conn {:labels [:person] :props {:first-name "Neo"}} [:person :salesman])

Update Node or Relationship (properties)

To change the properties of a node or relationship we have added two convenience functions. Both the update-props! and replace-props! functions takes a lookup representation as second argument.

To learn more about the Clojure representation of a lookup entry please see our representations page

Update properties

This function takes a connection, a lookup representation and the property map to update matched entities with.

It will update an existing properties map based on the following rules.

  • Keys existing only in the given property map is added to the object
  • Keys existing only in the property map on the found object is kept as is
  • Keys existing in both property maps are updated with values from the given property map
(client/update-props! conn {:labels [:person] :first-name "Thomas"} {:first-name "Neo"})

Replace properties

This function takes a connection, a lookup representation and the property map to replace the property map on matched entities with.

(client/replace-props! conn {:labels [:person] :first-name "Thomas"} {:last-name-only "Anderson"})

So in the example we find all nodes with label :person and the property key value pair :first-name "Thomas" and replace the whole property map, not only the key :first-name with the property-map {:last-name-only "Anderson"}

Delete Node or Relationship

The delete! function takes a lookup representation as second argument and deletes all matches.

Notice: You need to ensure you have deleted all relatiohsips to a node before you can delete the node.

To learn more about the Clojure representation of a lookup entry please see our representations page

(client/delete! conn {:labels [:person] :first-name "Neo"})

Graph CRUD

This section shows how to do basic CRUD operations on a whole graph through Neo4clj convenience functions.

Create Graph

To make it easier to create nodes and relationships, we have made a function to do it in one single call.

The lookups key specifies a vector of lookup representations referring existing nodes in the database.

The nodes key specifies a vector of node representations to create.

The relatioships key specifies a vector of relationship representations to create. It is possible to use ref-id from the lookups vector in the to and from keys of the relationship.

The returns key specifies a vector of ref-id from the other three keys to return as the result of the call.

(client/create-graph!
  conn
  {:lookups       [{:ref-id "c" :labels [:city] :props {:name "New York"}}]
   :nodes         [{:ref-id "p" :labels [:person] :props {:first-name "Neo"}}]
   :relationships [{:type :lives-in :from {:ref-id "p"} :to {:ref-id "c"} :props {:born-here false}}]
   :returns       ["c" "p"]})

Get Graph

To make it easier to fetch nodes and relationships, we have made a function to do it all in one single call.

The relatioships key specifies a vector of relationship representations which needs to exists between the nodes to match.

The returns key specifies a vector of ref-id from the other two keys to return as the result of the call.

(client/get-graph
  conn
  {:relationships [{:ref-id "r"
                    :type :lives-in
                    :from {:ref-id "p" :labels [:person] :props {:first-name "Neo"}}
                    :to {:ref-id "c" :labels [:city]}}]
   :returns       ["c" "p" "r"]})

Using operators for relationships

To make more advanced graph specifications to fetch from Neo4j, we have support for simple operators. These exists in the namespace neo4clj.operator

Notice that relationship representations with the not-exists operator doen't require the ref-id key and if no operator is used exists will be used by default.

In this example we are looking for persons with the first name "Neo" currently living in "New York", but is not born there

(require '[neo4clj.operator :as op])

(def person {:ref-id "p" :labels [:person] :props {:first-name "Neo"}})

(def city {:ref-id "c" :labels [:city] :props {:city "New York"}})

(client/get-graph
  conn
  {:relationships [(op/exists
                     {:ref-id "r"
                      :type :lives-in
                      :from person
                      :to city})
                   (op/not-exists
                     {:type :born-in
                      :from person
                      :to city})]
   :returns       ["c" "p" "r"]})

Create and drop indexes

To help handling index creation and drops, we have added convenience functions for theese operations

Create index

Create an index on a single property

(client/create-index! conn :person [:first-name])

Create an index across multiple properties

(client/create-index! conn :person [:first-name :last-name])

Drop index

Drop an index on a single property

(client/drop-index! conn :person [:first-name])

Drop an index across multiple properties

(client/drop-index! conn :person [:first-name :last-name])

Sessions and Transactions

This section describes how to execute several queries in a session or transaction.

Execute multiple queries in a session

By default all the operations you run in Neo4clj will be run in a separate session, but if you want to run multiple queries in a session you can do it as shown below.

(client/with-session conn session
  (client/create-node! session {:ref-id "p" :labels [:person] :props {:first-name "Neo"}})
  (client/create-node! session {:ref-id "p" :labels [:person] :props {:first-name "Morpheus"}}))

Notice the session variable is a placeholder, you can use as the connection in your queries.

Execute multiple queries in a transaction

Running queries in a transaction ensures all queries are run without errors before commiting the changes to Neo4j. In Neo4clj all transactions are auto-commiting on sucess.

Simple transaction

(client/with-transaction conn transaction
  (client/create-node! transaction {:ref-id "p" :labels [:person] :props {:first-name "Neo"}})
  (client/create-node! transaction {:ref-id "p" :labels [:person] :props {:first-name "Morpheus"}}))

Notice the transaction variable is a placeholder, you can use as the connection in your queries.

Transaction with rollback

By default all exceptions occuring within the body of the with-transaction will result in a roll-back, but it is also possible to do a manual rollback as shown below.

(client/with-transaction conn transaction
  (client/create-node! transaction {:ref-id "p" :labels [:person] :props {:first-name "Neo"}})
  (client/create-node! transaction {:ref-id "p" :labels [:person] :props {:first-name "Morpheus"}})
  (client/rollback transaction))

Notice the transaction variable is a placeholder, you can use as the connection in your queries.

You can’t perform that action at this time.