codex-ogm

5.0.0 • Public • Published

Codex OGM

Build Status devDependency Status Coverage Status npm version Slack Status

Build a graph and query it.

Powered by Neo4j 3, Bolt, and cypher-stream.

Install

npm install --save codex-ogm

Neo4j

Requires Neo4j 3 running on localhost with the following configurations:

# Enable auto-indexing for nodes, default is false
dbms.auto_index.nodes.enabled=true
# The node property keys to be auto-indexed, if enabled
dbms.auto_index.nodes.keys=id

Using Docker:

mkdir -p ~/.neo4j/conf
cp -R ./test/conf ~/.neo4j/conf
docker run -d --publish=7474:7474 --publish=7687:7687 --volume ~/.neo4j/conf:/conf neo4j:3.0

Example Usage

Creating a Tree with Access Control

See ./test/make-tree.js and ./test/access-control-test.js.

var ogm = require('codex-ogm');
var ogm     = require('./index');
var R       = require('ramda');
var Promise = require('bluebird');

var Node = ogm.Graph.Node;
var User = ogm.Graph.User;

var db = ogm.db();
var tx = db.createTransaction();
var log = console.log.bind(console);

var addChild = R.curry((tx, parent, child) => parent.addChild(child).save(tx))
var fiveTimes = R.times(R.__, 5);

// Node parent -> String type -> Promise<Node[]>
var createFiveChildren = R.curry((tx, type, parent) =>
  Promise
  .all(fiveTimes(
    i =>
      Promise.resolve(
        new Node(type, { name: `${type} ${i}`, i })
        .save(tx)
      )
      .tap(addChild(tx, parent, R.__))
  )))
;

var users = Promise
  .all(['Bob', 'Sue'])
  .map(name =>
    new User({ name })
    .save(tx)
  )
;

var nodes = Promise.resolve(
  new Node('Parent', { name: 'Parent' })
  .save(tx)
)
.then(parent =>
  createFiveChildren(tx, 'Child', parent)
  .then(children =>
    Promise.all(children)
    .map(createFiveChildren(tx, 'Grand Child'))
    .then(R.flatten)
    .then(grandChildren => ({ parent, children, grandChildren }))
  )
);

Promise.all([ users, nodes ])
.tap(([ [ bob, sue ], { parent, children } ]) => Promise.all([
  bob.grantAccessTo(parent).save(tx),
  sue.grantAccessTo(children[3]).save(tx)
]))
.tap(log)
.finally(() => {
  tx.commit();
})
;

The resulting graph

The resulting graph.

Reading From the Graph

Find a Node by ID

  context('given a saved node', () => {
    var node;
    var db = ogm.db();

    beforeEach(function (done) {
      var tx = db.createTransaction();
      node = new ogm.Graph.Node('Test', { foo: 'Bar' });
      node.save(tx);
      tx.on('end', done);
      tx.commit();
    });

    it('can find it by id', done => {
      var callback = sinon.spy();
      var tx = db.createTransaction();

      tx.concat(ogm.Graph.Node.findById(node.getId()));

      tx.forEach(callback);
      tx.forEach(result => {
        result.node.equals(node).should.equal(true);
      });

      tx.on('end', () => {
        callback.should.have.callCount(1);
        done();
      });

      tx.commit();

    });

  });

Find Related Nodes

See ./test/find-related-tests.js for more examples.

it('finds grand children', done => {

  var callback = sinon.spy();
  var db       = ogm.db();
  var tx       = db.createTransaction();

  tx.concat(parent.findRelated(['Child', 'Grand Child']));

  tx.forEach(callback);

  tx.on('end', () => {
    callback.should.have.callCount(25);
    done();
  });

  tx.commit();
});

Additionally supports sorting, filtering, searching, and returning a subset of properties.


Check the tests for more examples.

Readme

Keywords

none

Package Sidebar

Install

npm i codex-ogm

Weekly Downloads

1

Version

5.0.0

License

ISC

Last publish

Collaborators

  • brian.g.gates