Search code examples
neo4jneo4jclient

Optimizing GraphClient Connection?


Below you will see my GraphOperations class (written in C# using Neo4jClient) that performs basic Neo4j graph operations. The GraphGetConnection() method connects to Neo4j and returns clientConnection and my CreateNode() method created a node and returns its node reference.

Now in that method you will see that Im going GraphOperations graphOp = new GraphOperations(); and then clientConnection= graphOp.GraphConnection();.

  1. Is this the right way to do this?
  2. Do I call a connection every time I want to perform an operation?
  3. How do I optimize this code below? I want to create a method for each CRUD operation and want to find the best way to do this.

I hope the question is clear enough?

using Neo4jClient;

public class GraphOperations
{
    GraphClient clientConnection;

    public GraphClient GraphGetConnection()
    {
        clientConnection = new GraphClient(new Uri("http://localhost:7474/db/data"));
        clientConnection.Connect();

        return clientConnection;
    }

    public long GraphCreateNode(string type, string name, string customerName, string documentReference, int newVersionNumber)
    {

        Guid nodeGuid = Guid.NewGuid();
        System.DateTime dateTime = System.DateTime.Now;
        string timeStamp = String.Format("{0:dd MMMM yyyy HH:mm:ss}", dateTime);

        GraphOperations graphOp = new GraphOperations();
        clientConnection = graphOp.GraphGetConnection();

        var createNode = clientConnection.Create(new VersionNode()
        {
            GUID = nodeGuid.ToString(),
            Name = name,
            Type = type,
            DocumentReference = documentReference,
            DateTimeCreated = timeStamp,
            Version = newVersionNumber
        });

        return createNode.Id;
    }
}

Solution

  • Well, you are already storing the GraphClient in the GraphOperations class, and as your GraphCreateNode method isn't static, you could just use that field, so your GraphCreateNode method becomes something like:

    public long GraphCreateNode(string type, string name, string customerName, string documentReference, int newVersionNumber)
    {
        /* CODE */
        this.GraphGetConnection(); //Don't care or need the return from GraphGetConnection
        //From then on just:
        clientConnection.DOSTUFF ....
        /* CODE */
    

    Personally, I would change a few things to make life a bit easier for yourself:

    public class GraphOperations 
    {
        private GraphClient clientConnection;
        private void InitializeGraphClient()
        {
            if(this.clientConnection != null)
                return;
    
            this.clientConnection = new GraphClient(new Uri("http://localhost:7474/db/data"));
            this.clientConnection.Connect();
        }
    
        public NodeReference CreateNode(/*parameters*/) 
        {
            InitializeGraphClient();
    
            Guid nodeGuid = Guid.NewGuid();
            System.DateTime dateTime = System.DateTime.Now;
            string timeStamp = String.Format("{0:dd MMMM yyyy HH:mm:ss}", dateTime);
    
            var createNode = this.clientConnection.Create(
                new VersionNode()
                        {
                            GUID = nodeGuid.ToString(),
                            Name = name,
                            Type = type,
                            DocumentReference = documentReference,
                            DateTimeCreated = timeStamp,
                            Version = newVersionNumber
                        });
    
            return createNode.Id;
        }
    }
    

    In each method (CRUD-wise) you'll call InitializeGraphClient and that will make sure the connection is there. The other way (and this might be preferable) is to stick that initialization into the constructor for GraphOperations:

    public class GraphOperations 
    {
        private readonly GraphClient clientConnection;
        public GraphOperations()
        {
            this.clientConnection = new GraphClient(new Uri("http://localhost:7474/db/data"));
            this.clientConnection.Connect();
        }
    
        public NodeReference CreateNode(/*parameters*/) 
        {
            Guid nodeGuid = Guid.NewGuid();
            System.DateTime dateTime = System.DateTime.Now;
            string timeStamp = String.Format("{0:dd MMMM yyyy HH:mm:ss}", dateTime);
    
            var createNode = this.clientConnection.Create(
                new VersionNode()
                        {
                            GUID = nodeGuid.ToString(),
                            Name = name,
                            Type = type,
                            DocumentReference = documentReference,
                            DateTimeCreated = timeStamp,
                            Version = newVersionNumber
                        });
    
            return createNode.Id;
        }
    }
    

    and using that you should always know that the GraphClient instance will be there, which means your CRUD methods can focus on doing CRUD and not initializing the GraphClient. There is the potential with this that an Exception could be thrown from the constructor, but as to whether that is a bad thing or not is personal preference.