in-memory graph database for modern browsers
Project maintained by Zuudo
HeliosJS is an in-memory graph database for modern browsers. It employs a non-blocking asynchronous architecture through the use of Promises and Web Workers, and therefore is only available in browsers that support Web Workers. This enables HeliosJS to download and process large data sets without blocking the UI.
In order to traverse the graph, HeliosJS uses a Gremlin inspired graph traversal language to query, analyze and manipulate the graph. Gremlin is an open source project maintained by TinkerPop. For more information on Gremlin, see the Gremlin wiki.
Please use the HeliosJS mailing list for all HeliosJS related questions. For TinkerPop related discussions, use the Gremlin-Users mailing list.
Copy the helios directory to your project's root directory. Then reference the helios.js file and it's dependancies from the script tags.
<script src="./helios/lib/q.min.js"></script>
<script src="./helios/lib/uuid.js"></script>
<script src="./helios/lib/q-comm.js"></script>
<script src="./helios/helios.js"></script>
N.B. Unless otherwise noted, all samples are derived from the TinkerPop "toy" graph. The hardcoded representation of the graph is diagrammed here.
Now create a graph database.
var graph = new Helios.GraphDatabase();
N.B. GraphDatabase also takes a parameter which specifies the location of heliosDB.js. This is the file that the web worker uses to create the Helios graph. The default location is './helios/lib/heliosDB.js'. However, if you need to move the file to a different location, you will need to pass the new location to GraphDatabase so Helios knows where to find the file. GraphDatabase takes an object with a property key of 'heliosDBPath'. For example:
var graph = new Helios.GraphDatabase({heliosDBPath:'./new/directory/location/heliosDB.js'});
Load some data. Then travese the graph.
graph.loadGraphSON('./location/to/json/data.json')
.then(function(g){
g.V().out('knows').then(function(result){console.log(JSON.stringify(result))});
}, function(err){
console.error(err);
});
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"}
,{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
Lets break this down. The first step creates a variable 'graph' that references the graph database.
The next step loads data into the database using the loadGraphSON function. This function accepts GraphSON "NORMAL" mode format. If this call is successful it returns a reference to the graph 'g'. All calls against the database will be made with this variable.
We then travese the graph. What the above query is doing is retrieving all 'out' going vertices that 'knows' a related vertex. Once the data is retrieved 'then' returns the result. The return value, in this instance, is an array of Vertex objects.
Function calls are able to be chained, because each call returns a Pipeline object, which is the object that pipes the data through each of the function calls. Once 'then' is called, the pipeline is closed and the result is emitted.
Function signatures are based on the TypeScript notation. Which essentially is (variable name:Type). However, there are some little differences. One of which is the elipsis notation. When you encounter something like (...id:number[]), this is saying that you can optionally pass in and array of ids of Type number OR a comma separated list of ids of Type number.
Functions listed multiple times with different signatures signify that the function is overloaded.
Data Type of 'Element' refers to either a Vertex or Edge object.
Unless otherwise specified, all examples assume that the 'then' function is called with the output converted to JSON. For example:
heliosjs> g.v(4).then(function(result){console.log(JSON.stringify(result))});
output:
[{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
will be shown as:
heliosjs> g.v(4)
output:
[{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
Gremlin comes in a number of different language variants. One of which is Groovy, which is what the Helios traversal language is based on. Groovy has a construct called Closures which are essentially anonymous functions and take the form of { [closureArguments->] statements }. In order to keep the traversal language as close to Gremlin as possible, Helios does it's best to mimic Closures. For simplicity, I refer to them as "closures" but they really aren't Closures.
To use closures is quiet simple. All you need to remember are 2 things:
It'll become a little clearer once you take a look at a few examples below.
Transform steps take an object and emit a transformation of it.
Transform emits the result of a closure.
heliosjs> g.E().where({'weight':{$gt:0.5}}).outV().property('age')
output:
[29,32]
heliosjs> g.E().where({'weight':{$gt:0.5}}).outV().property('age').transform('it+2')
output:
[31,34]
heliosjs> g.E().where({'weight':{$gt:0.5}}).outV().transform('[it._id, it.age]')
output:
[[1,29],[4,32]]
heliosjs> g.E().where({'weight':{$gt:0.5}}).outV().transform('{id:it._id,age:it.age}')
output:
[{"id":1,"age":29},{"id":4,"age":32}]
The vertex iterator for the graph. Utilize this to iterate through all the vertices in the graph. Use with care on large graphs unless used in combination with a indexed key.
N.B. Uppercase V and lowercase V are inter-changeable. They take exactly the same parameters and have exactly the same output. i.e. V() == v()
heliosjs> g.V()
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
heliosjs> g.V(1)
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.V("1")
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v(1,4)
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> g.V([1,4])
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> g.V({name:{$eq:'marko'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.V({name:{$eq:'marko'}},{name:{$eq:'josh'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> g.v([{name:{$eq:'marko'}},{name:{$eq:'josh'}}])
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> g.V({name:{$eq:'marko'}}).property('name')
output:
["marko"]
heliosjs> g.V([{"name":"marko","_id":1},{"name":"josh","_id":4}])
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> g.V({"name":"marko","_id":1},{"name":"josh","_id":4})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
The edge iterator for the graph. Utilize this to iterate through all the edges in the graph. Use with care on large graphs. Can be used with indexed keys.
N.B. Uppercase E and lowercase E are inter-changeable. They take exactly the same parameters and have exactly the same output. i.e. E() == e()
heliosjs> g.E()
output:
[{"weight":0.5,"_id":7,"_type":"edge","_label":"knows","_out":1,"_in":2},
{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4},
{"weight":0.4,"_id":9,"_type":"edge","_label":"created","_out":1,"_in":3},
{"weight":1,"_id":10,"_type":"edge","_label":"created","_out":4,"_in":5},
{"weight":0.4,"_id":11,"_type":"edge","_label":"created","_out":4,"_in":3},
{"weight":0.2,"_id":12,"_type":"edge","_label":"created","_out":6,"_in":3}]
heliosjs> g.e().property("weight")
output:
[0.5,1,0.4,1,0.4,0.2]
Gets the unique identifier of the element.
heliosjs> g.V({name:{$eq:'marko'}},{name:{$eq:'josh'}}).id()
output:
[1,4]
heliosjs> g.V(1).out().id()
output:
[2,4,3]
Gets the label of an edge.
heliosjs> g.v(6).outE().label()
output:
["created"]
Gets the out adjacent vertices to the vertex.
heliosjs> g.v(1).out()
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]
heliosjs> g.v(1).out('knows')
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
Gets the outgoing edges to the vertex.
heliosjs> g.v(1).outE()
output:
[{"weight":0.5,"_id":7,"_type":"edge","_label":"knows","_out":1,"_in":2},
{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4},
{"weight":0.4,"_id":9,"_type":"edge","_label":"created","_out":1,"_in":3}]
heliosjs> g.v(1).outE('knows')
output:
[{"weight":0.5,"_id":7,"_type":"edge","_label":"knows","_out":1,"_in":2},
{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4}]
Gets the adjacent vertices to the vertex.
heliosjs> g.v(4).in()
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v(4).in('knows')
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
Gets the incoming edges of the vertex.
heliosjs> g.v(4).inE()
output:
[{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4}]
heliosjs> g.v(4).inE('knows')
output:
[{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4}]
Get both adjacent vertices of the vertex, the in and the out.
heliosjs> g.v(4).both()
output:
[{"name":"ripple","lang":"java","_id":5,"_type":"vertex"}
,{"name":"lop","lang":"java","_id":3,"_type":"vertex"}
,{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v(4).both('knows')
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v(4).both('knows', 'created')
output:
[{"name":"ripple","lang":"java","_id":5,"_type":"vertex"}
,{"name":"lop","lang":"java","_id":3,"_type":"vertex"}
,{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v(4).both(['knows', 'created'])
output:
[{"name":"ripple","lang":"java","_id":5,"_type":"vertex"}
,{"name":"lop","lang":"java","_id":3,"_type":"vertex"}
,{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
Get both incoming and outgoing edges of the vertex.
heliosjs> g.v(4).bothE()
output:
[{"weight":1,"_id":10,"_type":"edge","_label":"created","_out":4,"_in":5},
{"weight":0.4,"_id":11,"_type":"edge","_label":"created","_out":4,"_in":3},
{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4}]
heliosjs> g.v(4).bothE('knows','created')
output:
[{"weight":1,"_id":10,"_type":"edge","_label":"created","_out":4,"_in":5},
{"weight":0.4,"_id":11,"_type":"edge","_label":"created","_out":4,"_in":3},
{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4}]
Get both outgoing tail vertex of the edge.
heliosjs> g.e(12).outV()
output:
[{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Get both incoming head vertex of the edge.
heliosjs> g.e(12).inV()
output:
[{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]
Get both incoming and outgoing vertices of the edge.
heliosjs> g.e(12).inV()
output:
[{"name":"peter","age":35,"_id":6,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]
Get the property value of an element.
heliosjs> g.v(1).property('age')
output:
[29]
Gets the property map of the graph element.
heliosjs> g.v(1).map()
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v(1).map('name', 'age')
output:
[{"name":"marko","age":29}]
Gets the path through the pipeline up to this point, where closures are post-processing for each object in the path. If the path step is provided closures then, in a round robin fashion, the closures are evaluated over each object of the path and that post-processed path is returned.
heliosjs> g.v(1).out().path()
output:
[[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"}],
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}],
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]]
heliosjs> g.v(1).out().path('name','age')
output:
[[{"age":29,"name":"marko"},{"age":27,"name":"vadas"}],
[{"age":29,"name":"marko"},{"age":32,"name":"josh"}],
[{"age":29,"name":"marko"},{"name":"lop"}]]
heliosjs> g.v(1).out().path('it.id')
output:
[[1,2],[1,4],[1,3]]
g.v(1).out().path('it.id','id.name')
output:
[[1,"vadas"],[1,"josh"],[1,"lop"]]
heliosjs> g.v(1).outE().inV().property('name').path()
output:
[[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"weight":0.5,"_id":7,"_type":"edge","_label":"knows","_out":1,"_in":2},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},"vadas"],
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"weight":1,"_id":8,"_type":"edge","_label":"knows","_out":1,"_in":4},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},"josh"],
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"weight":0.4,"_id":9,"_type":"edge","_label":"created","_out":1,"_in":3},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},"lop"]]
Select the named steps to emit after select with post-processing closures in a round robin.
heliosjs> g.v(1).as('x').out('knows').as('y').select()
output:
[[{"x":{"name":"marko","age":29,"_id":1,"_type":"vertex"}},
{"y":{"name":"vadas","age":27,"_id":2,"_type":"vertex"}}],
[{"x":{"name":"marko","age":29,"_id":1,"_type":"vertex"}},
{"y":{"name":"josh","age":32,"_id":4,"_type":"vertex"}}]]
heliosjs> g.v(1).as('x').out('knows').as('y').select(["y"])
output:
[[{"y":{"name":"vadas","age":27,"_id":2,"_type":"vertex"}}],
[{"y":{"name":"josh","age":32,"_id":4,"_type":"vertex"}}]]
heliosjs> g.v(1).as('x').out('knows').as('y').select(["y"],'it.name')
output:
[[{"y":"vadas"}],[{"y":"josh"}]]
heliosjs> g.v(1).as('x').out('knows').as('y').select(["y"],'it._id','it.name')
output:
[[{"y":2}],[{"y":"josh"}]]
heliosjs> g.v(1).as('x').out('knows').as('y').select('it._id','it.name')
output:
[[{"x":1},{"y":"vadas"}],[{"x":1},{"y":"josh"}]]
heliosjs> g.v(1).as('x').out('knows').as('y').select(['x','y'],'it._id','it.name','it.age')
output:
[[{"x":1},{"y":"vadas"}],[{"x":29},{"y":4}]]
Returns a JavaScript Object Notation (JSON) string.
heliosjs> g.v(1).stringify().then(function(r){return console.log(r)});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
Returns a hash Object with the ids as the key.
heliosjs> g.v(1,4).hash()
output:
{"1":{"name":"marko","age":29,"_id":1,"_type":"vertex"},
"4":{"name":"josh","age":32,"_id":4,"_type":"vertex"}}
Order the items in the stream according to the criteria if provided. If no criteria is provided, then a default sort order is used. The default sort order is ascending, case-sensitive with values that are numeric in nature sorted as numbers (i.e. '$20.05' is treated as 20.05). If the incoming values are elements then the elements will be sorted on id. The desc argument is a minus sign passed as a string to indicate descending order.
The properties parameter can be passed in as a list or an array and accepts either a property name or a sort object (eg. {'key':'default'}). To set descending order, prefix the property name with '-' (e.g. '-name'). Sort objects provide more information to the order step, as mentioned above, use the property name as the key and one of
If a specified property does not exist in the object the default action is to place the object at the bottom (top if order descending)
heliosjs> g.v(1).out().order()
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> g.v(1).out('-').order()
output:
[{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"}]
heliosjs> g.v(1).out().property('name').order()
output:
["josh","lop","vadas"]
heliosjs> g.v(1).out('-').property('name').order()
output:
["vadas","lop","josh"]
Test data for the follow order() examples can be found here.
heliosjs> g.v().map('name','age')
output:
[{"age":29,"name":"marko"},
{"age":27,"name":"vadas"},
{"name":"lop"},
{"age":29,"name":"Marko"},
{"name":"ripple"},
{"age":35,"name":"peter"}]
heliosjs> g.v().map('name','age').order('name')
output:
[{"age":29,"name":"Marko"},
{"name":"lop"},
{"age":29,"name":"marko"},
{"age":35,"name":"peter"},
{"name":"ripple"},
{"age":27,"name":"vadas"}]
heliosjs> g.v().map('name','age').order('-name')
output:
[{"age":27,"name":"vadas"},
{"name":"ripple"},
{"age":35,"name":"peter"},
{"age":29,"name":"marko"},
{"name":"lop"},
{"age":29,"name":"Marko"}]
heliosjs> g.v().map('name','age').order({'-name':'case-i'})
output:
[{"age":27,"name":"vadas"},
{"name":"ripple"},
{"age":35,"name":"peter"},
{"age":29,"name":"marko"},
{"age":29,"name":"Marko"},
{"name":"lop"}]
heliosjs> g.v().map('name','age').order('age','name')
output:
[{"age":27,"name":"vadas"},
{"age":29,"name":"Marko"},
{"age":29,"name":"marko"},
{"age":35,"name":"peter"},
{"name":"lop"},
{"name":"ripple"}]
heliosjs> g.v().map('name','age').order('age',{'name':'case-i'})
output:
[{"age":27,"name":"vadas"},
{"age":29,"name":"marko"},
{"age":29,"name":"Marko"},
{"age":35,"name":"peter"},
{"name":"lop"},
{"name":"ripple"}]
Filter steps decide whether to allow an object to pass to the next step or not.
Decide whether to allow an object to pass. Return true from the closure to allow an object to pass.
heliosjs> g.V().filter('it.age > 29').property('name')
output:
["josh","peter"]
A index filter that emits the particular indexed objects.
heliosjs> g.V().index(0).property('name')
output:
["marko"]
heliosjs> g.V().index(0, 2).property('name')
output:
["marko", "lop"]
A range filter that emits the objects within a range.
heliosjs> g.V().range(0,2).property('name')
output:
["marko","vadas","lop"]
heliosjs> g.V().range(2).property('name')
output:
["lop","josh","ripple","peter"]
Go back to the results from n-steps ago, where the preceding step is step 0, or go back to the results of a named step.
heliosjs> g.V().out('knows').where({'age':{$gt:30}}).back(2).property('age')
output:
[29]
heliosjs> g.V().as('x').outE('knows').inV().where({'age':{$gt:30}}).back('x')
output:
[29]
Emit only incoming objects that have not been seen before.
heliosjs> g.v(1).out().in().id()
output:
[1,1,1,4,6]
heliosjs> g.v(1).out().in().dedup().id()
output:
[1,4,6]
Emit everything to pass except what is in the supplied collection.
heliosjs> var x = [[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]]
heliosjs> g.V().except(x)
output:
[{"name":"peter","age":35,"_id":6,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> x = [1,2,3];
heliosjs> g.V().except(x)
output:
[{"name":"peter","age":35,"_id":6,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
Allow everything to pass except what is not in the supplied collection.
heliosjs> var x = [[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]]
heliosjs> g.V().retain(x)
output:
[{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> x = [1,2,3];
heliosjs> g.V().retain(x)
output:
[{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
Emit only incoming objects that meet the specified criteria of the comparator.
If you are familiar with Gremlin, where
replaces the following Gremlin steps:
and could even be used instead of the filter
step.
Comparators are Object literals. In order to use comparators you create an object literal and use the key value that you would like to match as the key of the object. The value of this property is the comparator object. For example, to find an element where 'name' is equal to 'marko', you would pass in the following:
{name:{$eq:'marko'}}
If a specified property does not exist in the element, the element is ignored and not included in the results.
All comparator selectors are able to access object properties, as well as embedded object properties. Use the 'dot' notation to access embedded properties, ensuring that the key is a string.
Comparison selectors work with values and arrays.
Takes a single argument and matches values equal to the value specified.
heliosjs> g.v().where({name:{$eq:'marko'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
Takes a single argument and matches values not equal to the value specified.
heliosjs> g.v().where({name:{$neq:'marko'}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
heliosjs> g.v().where({age:{$neq:29}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Takes a single argument and matches values less than to the value specified.
heliosjs> g.v().where({age:{$lt:29}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"}]
Takes a single argument and matches values less than or equal to to the value specified.
heliosjs> g.v().where({age:{$lte:29}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"}]
Takes a single argument and matches values greater than to the value specified.
heliosjs> g.v().where({age:{$gt:29}})
output:
[{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Takes a single argument and matches values greater than equal to the value specified.
heliosjs> g.v().where({age:{$gte:29}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Takes an array argument with a length of 2 and matches values between and inclusive of the values specified. i.e. [from, to]
heliosjs> g.v().where({age:{$btw:[29,32]}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
Takes either a single argument or an array of values and matches values equal to the values specified.
heliosjs> g.v().where({age:{$in:[29,35]}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Takes either a single argument or an array of values and matches values not equal to the values specified.
heliosjs> g.v().where({age:{$ex:[29,35]}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
Takes either a single regex argument or an array of regex values and matches values based on the values specified.
heliosjs> g.v().where({name:{$like:'ma'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v().where({name:{$like:['ete','das']}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Takes a single argument and matches values starting with the values specified.
heliosjs> g.v().where({name:{$startsWith:'ma'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
Takes a single argument and matches values ending with the values specified.
heliosjs> g.v().where({name:{$endsWith:'das'}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex"}]
Array selectors work with arrays.
Test data for these examples can be found here.
Takes an array of values and matches values if all values specified are contained in an array.
heliosjs> g.v().where({dow:{$all:['mon','wed']}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex","dow":["mon","tue","wed"],"dob":"1984-05-05","active":true,"budget":"$120,000","device":{"qty":3,"mobile":{"phone":["iphone","samsung"],"tablet":["galaxy"]}}},
{"name":"vadas","age":27,"_id":2,"_type":"vertex","dow":["mon","wed"],"dob":"1986-03-12","active":false,"budget":"$100,000","device":{"qty":1,"mobile":{"phone":["iphone"]}}}]
Takes an array of values and matches values if the target array has exactly the same values.
heliosjs> g.v().where({dow:{$match:['mon','wed']}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex", "dow":["mon", "wed"], "dob":"1986-03-12", "active":false, "budget":"$100,000", "device":{"qty":1,"mobile":{"phone":["iphone"]}}}]
Takes an integer or string comparison value and matches arrays that have a length the matches the value specified.
heliosjs> g.v().where({dow:{$len:2}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex","dow":["mon","wed"],"dob":"1986-03-12","active":false,"budget":"$100,000","device":{"qty":1,"mobile":{"phone":["iphone"]}}},
{"name":"peter","age":35,"_id":6,"_type":"vertex","dow":["mon","fri"],"dob":"1978-12-13","active":true,"budget":"$70,000","device":{"qty":2,"mobile":{"phone":["iphone"],"tablet":["ipad"]}}}]
heliosjs> g.v().where({dow:{$len:'==2'}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex","dow":["mon","wed"],"dob":"1986-03-12","active":false,"budget":"$100,000","device":{"qty":1,"mobile":{"phone":["iphone"]}}},
{"name":"peter","age":35,"_id":6,"_type":"vertex","dow":["mon","fri"],"dob":"1978-12-13","active":true,"budget":"$70,000","device":{"qty":2,"mobile":{"phone":["iphone"],"tablet":["ipad"]}}}]
heliosjs> g.v().where({dow:{$len:'=== 2'}})
output:
[{"name":"vadas","age":27,"_id":2,"_type":"vertex","dow":["mon","wed"],"dob":"1986-03-12","active":false,"budget":"$100,000","device":{"qty":1,"mobile":{"phone":["iphone"]}}},
{"name":"peter","age":35,"_id":6,"_type":"vertex","dow":["mon","fri"],"dob":"1978-12-13","active":true,"budget":"$70,000","device":{"qty":2,"mobile":{"phone":["iphone"],"tablet":["ipad"]}}}]
heliosjs> g.v().where({dow:{$len:'>2'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex","dow":["mon","tue","wed"],"dob":"1984-05-05","active":true,"budget":"$120,000","device":{"qty":3,"mobile":{"phone":["iphone","samsung"],"tablet":["galaxy"]}}}]
heliosjs> g.v().where({dow:{$len:'>= 2'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex","dow":["mon","tue","wed"],"dob":"1984-05-05","active":true,"budget":"$120,000","device":{"qty":3,"mobile":{"phone":["iphone","samsung"],"tablet":["galaxy"]}}},
{"name":"vadas","age":27,"_id":2,"_type":"vertex","dow":["mon","wed"],"dob":"1986-03-12","active":false,"budget":"$100,000","device":{"qty":1,"mobile":{"phone":["iphone"]}}},
{"name":"peter","age":35,"_id":6,"_type":"vertex","dow":["mon","fri"],"dob":"1978-12-13","active":true,"budget":"$70,000","device":{"qty":2,"mobile":{"phone":["iphone"],"tablet":["ipad"]}}}]
{
name:{$eq:'marko'},
age:{$eq:29}
}
heliosjs> g.v().where({name:{$eq:'marko'}, age:{$eq:29}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
{name:{$eq:'marko'}},
{name:{$eq:'vadas'}}
heliosjs> g.v().where({name:{$eq:'marko'}},{name:{$eq:'vadas'}})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"}]
heliosjs> g.v().where([{name:{$eq:'marko'}},{age:{$gt:'30'}}])
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
NOT logic is handled by the inverse operators already explained above. For intance, the inverse operator for $eq is $neq.
NOR needs to be explicitly declared, so gets it's own operator ($nor). NOR returns elements that fail to meet all clauses. To use $nor, you create an object literal that holds an array of regular comparator expressions.
{$nor:[{name:{$eq:'marko'}},{name:{$eq:'vadas'}}] }
heliosjs> g.v().where({$nor:[{name:{$eq:'marko'}},{name:{$eq:'vadas'}}]})
output:
[{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Element selectors work with Element properties. However, they do not work in conjunction with the Comparators specified above.
Takes an array of key values and matches objects which contain any of the key values specified.
heliosjs> g.v().where({$has:['lang']})
output:
[{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"}]
heliosjs> g.v().where({$has:['age', 'name']})
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Takes an array of key values and matches objects which do not contain any of the key values specified.
heliosjs> g.v().where({$hasNot:['age']})
output:
[{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"}]
Side Effect steps pass the object, but yield some kind of side effect while doing so.
Counts the number of elements.
heliosjs> g.V().out('knows').count()
output:
2
Emits input, but names the previous step.
heliosjs> g.v().out('knows').where({age:{$gt:30}}).back(2).property('age')
output:
[29]
heliosjs> g.v().as('x').out('knows').where({age:{$gt:30}}).back('x').property('age')
output:
[29]
Behaves similar to back
except that it does not filter. It will go down a particular path and back up to where it left off. As such, its useful for yielding a sideeffect down a particular branch.
heliosjs> heliosjs> g.v().out('knows').where({age:{$gt:30}}).back(2)
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v().out('knows').where({age:{$gt:30}}).optional(2)
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
heliosjs> g.v().as('x').out('knows').where({age:{$gt:30}}).back('x')
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> g.v().as('x').out('knows').where({age:{$gt:30}}).optional('x')
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"vadas","age":27,"_id":2,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Allows for if-then-else conditional logic.
heliosjs> g.v(1).out().ifThenElse("it.name=='josh'","it.age","it.name")
output:
["vadas",32,"lop"]
Loop over a particular set of steps in the pipeline. The first argument is either the number of steps back in the pipeline to go, where the preceding step is back 1 step, or a named step. The second argument is the number of iterations to loop. The final argument is known as the "emit" closure. This boolean-based closure will determine wether the current object in the loop structure is emitted or not. As such, it is possible to emit intermediate objects, not simply those at the end of the loop.
heliosjs> g.v(1).out().out()
output:
[{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]
heliosjs> g.v(1).out().loop(1,2)
output:
[{"name":"ripple","lang":"java","_id":5,"_type":"vertex"},
{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]
heliosjs> g.v(1).out().loop(1,2,"it.name=='josh'")
output:
[{"name":"josh","age":32,"_id":4,"_type":"vertex"}]
heliosjs> g.v(1).out().in().out().in().id()
output:
[1,1,1,4,6,1,1,1,4,6,1,1,1,4,6,4,1,4,6,1,4,6]
heliosjs> g.v(1).out().as('x').in().loop('x',2).id()
output:
[1,1,1,4,6,1,1,1,4,6,1,1,1,4,6,4,1,4,6,1,4,6]
Methods that operate on the database and do not directly travese the graph.
Pins the traversal to a point in the graph.
If you assign a traversal command to a variable, the variable holds a reference to that point in the graph. You can continue traversing the graph using the stored position, however the variable will store the last place reached during the last traversal. Pin ensures that the variable keeps the reference to the initial point in the graph.
heliosjs> g.v(1).out().in().in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> var dynamic = g.v(1).out();
heliosjs> dynamic.in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
heliosjs> dynamic.in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
heliosjs> var pinned = g.v(1).out().pin();
heliosjs> pinned.in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
heliosjs> pinned.in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
Restores default traversal behaviour on a previously pinned variable.
heliosjs> var pinned = g.v(1).out().pin();
heliosjs> pinned.in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
heliosjs> pinned.unpin();
heliosjs> pinned.in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"marko","age":29,"_id":1,"_type":"vertex"},
{"name":"josh","age":32,"_id":4,"_type":"vertex"},
{"name":"peter","age":35,"_id":6,"_type":"vertex"}]
heliosjs> pinned.in().then(function(r){return console.log(JSON.stringify(r))});
output:
[{"name":"marko","age":29,"_id":1,"_type":"vertex"}]
Loads "NORMAL" mode formatted GraphSON data into the database. Calling this function with new data appends the data and updates existing elements based on id.
heliosjs> g.loadGraphSON('http://path/to/graphson.json');
Loads GraphML formatted data into the database. Calling this function with new data appends the data and updates existing elements based on id.
heliosjs> g.loadGraphML('http://path/to/graphml.xml');
Closes the database.
heliosjs> g.shutdown();
(MIT License)
Copyright (c) 2012-2015 Entrendipity Pty. Ltd.
Copyright (c) 2015 Zuudo Pty. Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.