diff --git a/lib/Node._coffee b/lib/Node._coffee index f2602cd..8fd809b 100644 --- a/lib/Node._coffee +++ b/lib/Node._coffee @@ -502,3 +502,46 @@ module.exports = class Node extends PropertyContainer catch error throw adjustError error + + traverse: (returnType, options={}, _) -> + try + type = encodeURIComponent returnType + traverseURL = @_data['traverse']?.replace '{returnType}', type + + if not traverseURL + throw new Error 'Traverse not available.' + + res = @_request.post + url: traverseURL + json: options + , _ + + if res.statusCode isnt status.OK + throw new Error "Unrecognized response code: #{res.statusCode}" + + data = res.body + + switch type + when 'node' + return data.map (data) => new Node @db, data + when 'relationship' + return data.map (data) => + if @self is data.start + new Relationship @db, data, this, null + else + new Relationship @db, data, null, this + when 'path' + start = new Node this, {self: data.start} + end = new Node this, {self: data.end} + length = data.length + nodes = data.nodes.map (url) => + new Node this, {self: url} + relationships = data.relationships.map (url) => + new Relationship this, {self: url, type} + return new Path start, end, length, nodes, relationships + else + return null; + + catch error + throw adjustError error + diff --git a/test/traverse._coffee b/test/traverse._coffee new file mode 100644 index 0000000..02efe64 --- /dev/null +++ b/test/traverse._coffee @@ -0,0 +1,75 @@ +{expect} = require 'chai' +flows = require 'streamline/lib/util/flows' +neo4j = require '..' + +db = new neo4j.GraphDatabase 'http://localhost:7474' + +# seed nodes into graph +users = for i in [0..6] + db.createNode + name: "traversalTest#{i}" + +# node shortcut references +user0 = users[0] +user1 = users[1] +user2 = users[2] +user3 = users[3] +user4 = users[4] +user5 = users[5] +user6 = users[6] + +@traverse = + + '(pre-req) save nodes': (_) -> + flows.collect _, + for user in users + user.save not _ + + '(pre-req) create relationships': (_) -> + createFollowRelationships = (i, _) -> + user = users[i] + i1 = (i + 1) % users.length + i2 = (i + 2) % users.length + i3 = (i + 3) % users.length + flows.collect _, [ + user.createRelationshipTo users[i1], 'traverse_follows', {}, not _ + user.createRelationshipTo users[i2], 'traverse_follows', {}, not _ + user.createRelationshipTo users[i3], 'traverse_follows', {}, not _ + ] + + flows.collect _, + for user, i in users + createFollowRelationships i, not _ + + 'traverse connected nodes': (_) -> + nodes = user0.traverse 'node', { + order: 'breadth_first', + return_filter: { + body: """position.endNode().getProperty('name').contains('t')""", + language: 'javascript' + }, + prune_evaluator: { + body: 'none', + language: 'builtin' + }, + uniqueness: 'node_global', + relationships: [{ + direction: 'all', + type: 'traverse_follows' + }], + max_depth: 3 + }, _ + + expect(nodes).to.exist + expect(nodes).to.be.an 'array' + expect(nodes).to.have.length 7 + expect(nodes[0]).to.exist; + + nodes.forEach (node) => + expect(node.data).to.be.an 'object' + expect(node.data.name).to.contain 't' + +for name, test of @traverse + do (name, test) => + @traverse[name] = (_) -> + test _