1.0.3 • Published 7 years ago

@jekel18/neorm v1.0.3

Weekly downloads
-
License
ISC
Repository
-
Last release
7 years ago

NEORM

Description

A very simple neo4j javascript orm

Installation

npm install -S @jekel18/neorm

Import

const { Sequence, Graph } = require('@jekel18/neorm)

Usage

Sequence

The Sequence object is used to represent a cypher pattern. For example the following pattern:

MATCH (n:MOVIE) RETURN n

would be reprensent this way using the Sequence object

Sequence.node('Movie', 'n')

The node function allow two arguments: A descriptor and a tag. The tag is the name that will be use to identify the element inside the cypher query.

The descriptor can have multiple formats:

Sequence.node('Movie') // String representing a label
Sequence.node(['Movie', 'Person']) // Array of labels
const descriptor = {
    labels: ['Person'],
    born: 1954,
    name: 'Bob' 
};
Sequence.node(descriptor) // An object

To represent relationships, there is two possible methods: outRel and inRel. The outRel method representing an outgoing relationship and inRel and ingoing one.

Sequence.node('Person', 'person').outRel('ACTED_IN').node('Movie', 'movie').inRel('REVIEWD_BY').node('Person')

This would result in the following cypher

MATCH (person:Person)-[ACTED_IN]->(movie:Movie)<-[REVIEWD_BY]-(Person) RETURN person, movie
  • There is no limitation to the number of chained methods
  • Notice the how the tag arguments are used for the return statement of the cypher query
  • If the last method of the chain is a relationship, the pattern will be padded with an empty node

Conditional statement

A syntax similar to Mongoose and Sequelize can be used in the descriptor

const theMatrix = {
    title: { $or: ['The Matrix', 'The Matrix Reloaded']}
};
 
const actor = {
    labels: ['Person'],
    born: { $gte: 1960 }
};
 
const seq = Sequence.node(theMatrix, 'movies').inRel('ACTED_IN').node(actor, 'actors');  

Some operators can be used together:

// Find the actors born betweem 1950-1960 or 1970-1980
const theMatrix = {
    born: { $or: [ 
        { $and: [ { $gte: 1950 }, { $lte: 1960 } ] }, 
        { $and: [ { $gte: 1970 }, { $lte: 1980 } ] }, 
    ]}
};

Those are the supported operator so far:

  • $or
  • $and
  • $lt
  • $lte
  • $gt
  • $gte

##Graph

The Graph object is used to interact with the database.

Graph.connect('bolt://localhost', 'neo4j', 'mo49xw71');

####find Find node or relationship using a Sequence

const seq = Sequence.node(theMatrix, 'movies').inRel('ACTED_IN').node(actor, 'actors');
 
Graph
  .find(seq)
  .then(({ movies, actors }) => {
        // I am not sure this is the best way to return data, maybe return the row instean
  })
  .catch(ex => {})
  

You can also use other conditions on the query

Graph
    .find(seq)
    .limit(3)
    .skip(2)
    .sort('actors.name')
    .then(({ movies }) => {});

###findOne To find only one node

Graph
.findOne(Sequence.node({ id: 21 }, 'cuba'))
.then(({ cuba }) => Array.isArray(cuba)) // false
     

###createNode To create a new node

const Bill = {
    labels: ['Person'],
    born: 1986,
    name: 'Bill'
};
 
Graph.createNode(Bill)
 .then(console.log);
 

##The Node Object Each call to createNode, findOne or find return a node proxy around the original driver implementation https://neo4j.com/docs/api/javascript-driver/current/class/src/v1/graph-types.js~Node.html

The proxy has the following properties:

  • to access id: node.id
  • to access labels: node.labels
  • to access any other properties: node.property_name
  • to access the original object: node._target

    Also all the value of type Integer are converted on access

    The proxy also have a save function to update the node

    const Bill = { labels: 'Person', born: 1986, name: 'Bill' };

    Graph.createNode(Bill) .then(bill => { bill.lastName = 'bob'; return bill.save() // Update the node in the DB }) .then(newBill => { console.log(newBill.lastName) // bob });