HeliosJS

in-memory graph database for modern browsers

Project maintained by Zuudo

HeliosJS

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.

Getting Started

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.

Documentation Conventions

Function signatures

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"}]

Closures

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

Transform steps take an object and emit a transformation of it.

transform(closure:string)

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}]

top


V(...id:string[])

V(...id:number[])

V(...elements:Vertex[]) => object must have 'id' property.

V(...comparator:{}[])

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"}]

See Also

top


E(...id:string[])

E(...id:number[])

E(...elements:Edge[]) => object must have 'id' property.

E(...comparator:{}[])

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]

See Also

top


id()

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]

top


label()

Gets the label of an edge.

heliosjs> g.v(6).outE().label()
output:
["created"]

top


out(...labels:string[])

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"}]

top


outE(...labels:string[])

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}]

top


in(...labels:string[])

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"}]

top


inE(...labels:string[])

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}]

top


both(...labels:string[])

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"}]

top


bothE(...labels:string[])

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}]

top


outV()

Get both outgoing tail vertex of the edge.

heliosjs> g.e(12).outV()
output:
[{"name":"peter","age":35,"_id":6,"_type":"vertex"}]

top


inV()

Get both incoming head vertex of the edge.

heliosjs> g.e(12).inV()
output:
[{"name":"lop","lang":"java","_id":3,"_type":"vertex"}]

top


bothV()

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"}]

top


property(property:string)

Get the property value of an element.

heliosjs> g.v(1).property('age')
output:
[29]

top


map(...property:string[])

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}]

top


path(...property:string[])

path(...closure:string[])

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"]]

top


select(...closure:string[])

select(list:string[])

select(list:string[], ...closure:string[])

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}]]

top


stringify()

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"}]

top


hash()

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"}}

top


order()

order(desc:string)

order(...properties:any[])

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"}]

top


Filter

Filter steps decide whether to allow an object to pass to the next step or not.

filter(closure:string)

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"]

top


index(indices:number[])

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"]

top


range(start:number, end?:number)

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"]

top


back(backSteps:number)

back(namedStep:string)

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]

top


dedup()

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]

top


except(dataSet:Element[])

except(id:number[])

except(id:string[])

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"}]

See Also

top


retain(dataSet:Element[])

retain(id:number[])

retain(id:string[])

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"}]

See Also

top


where(comparator:{}[])

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.

Comparator Selectors

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

Comparison selectors work with values and arrays.

$eq

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"}]
$neq

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"}]
$lt

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"}]
$lte

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"}]
$gt

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"}]
$gte

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"}]
$btw

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"}]
$in

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"}]
$ex

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"}]
$like

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"}]
$startsWith

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"}]
$endsWith

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

Array selectors work with arrays.

Test data for these examples can be found here.

$all

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"]}}}]
$match

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"]}}}]
$len

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"]}}}]
Logical
The Logical selectors operate implicitly.
AND
Everything that is contained in a Comparator object is compared with AND logic. For example: If I wanted all elements with the name == marko AND age == 29, I would write the following:
{ 
 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"}]
OR
Subsequent Comparator objects are compared with OR logic. For example: If I wanted all elements with the name == marko OR name == vadas, I would write the following:
 {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

NOT logic is handled by the inverse operators already explained above. For intance, the inverse operator for $eq is $neq.

NOR - $nor

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

Element selectors work with Element properties. However, they do not work in conjunction with the Comparators specified above.

$has

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"}]
$hasNot

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"}]

top


Side Effect

Side Effect steps pass the object, but yield some kind of side effect while doing so.

count()

Counts the number of elements.

heliosjs> g.V().out('knows').count()
output:
2

top


as(name:string)

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]

top


optional(backSteps:number)

optional(namedStep:string)

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"}]

See Also

top


ifThenElse(ifClosure:string, thenClosure:string, elseClosure:string)

Allows for if-then-else conditional logic.

heliosjs> g.v(1).out().ifThenElse("it.name=='josh'","it.age","it.name")
output:
["vadas",32,"lop"]

top


loop(backSteps:number, iterations:number, closure?:string)

loop(namedStep:string, iterations:number, closure?:string)

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]

top


Database Methods

Methods that operate on the database and do not directly travese the graph.

pin()

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"}]

See Also

top


unpin()

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"}]

See Also

top


loadGraphSON(jsonData:string)

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');

top


loadGraphML(xmlData:string)

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');

top


shutdown()

Closes the database.

heliosjs> g.shutdown();

top


License

(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.