Skip to content
This repository has been archived by the owner on Jul 6, 2023. It is now read-only.
Luca Garulli edited this page Dec 10, 2013 · 32 revisions

N.B. Although orientdb-js will be the official JS driver for OrientDB, the library is currently in Alpha status and the API is subject to change. Please refer to the current JS driver, which is based on the Document Database interface and works synchronously. You can find it here: OrientDB JS driver.

About

The orientdb-js API is a javascript implementation of the Tinkerpop Gremlin graph traversal language with some extra goodies for working with OrientDB. orientdb-js tries to replicate Gremlin as closely as possible, however due to the nature of javascript there are some differences.

  • orientdb-js uses the Q module to return a Promise when making Ajax calls. All requests are invoked with then() and the callback is captured by then(result, error);.

  • All method calls require brackets (), even if there are no arguments. Closures do not translate to javascript. Closures need to passed in as a string argument to orientdb-js methods.

g.v(1).out().gather("{it.size()}");
g.v(1).out().ifThenElse("{it.name=='josh'}{it.age}{it.name}");
  • Float's are not native javascript Types so need to be passed in as a string to orientdb-js methods and need to be suffixed with a 'f'.
g.v(1).outE().has("weight", "T.gte", "0.5f").property("weight")
  • Certain methods cannot be implemented. Such as aggregate, store, table, tree and fill. These methods require a local object to populate with data, which cannot be done in this environment.

Usage

orientdb-js can be loaded using the following methods:

  • <script> tag in the browser.
<script type="text/javascript" src="orientdb-js.min.js"></script>

This exposes OrientDB variable to the browser.

  • via NPM
npm install orientdb-js

then in Node.js

var OrientDB = require('orientdb-js');

You will notice that in the examples tokens are passed as string (i.e. 'T.gt'). However, orientdb-js exposes some objects for convenience to make it feel more natural. To access thees objects reference them like so:

var T = OrientDB.T;
var Contains = OrientDB.Contains;
var Vertex = OrientDB.Vertex;
var Edge = OrientDB.Edge;

You can now use these objects in place of the string representation in your queries.

Connect to the remote server

To connect to a server use the connect method. The connect method accepts options which provide configuration details to orientdb-js.

Options

Options specify the location and name of the database.

host (default: localhost)

Location of OrientDB server

port (default: 2480)

OrientDB server port

graph (default: tinkergraph)

Graph database name

user (required)

Database user name.

password (required)

You usually obtain this from the config file

To override these, pass in an object with the required values. You also note that user and password are required values.

var orientdb = OrientDB.connect({ 'database': 'tinkerTest', 
                   'user': 'root',
                   'password': 'XXXXXXXXXX'});

Examples

For simplicity the callbacks are not included in the examples below.

Example 1: Basic Transforms

gremlin>  g.V('name', 'marko').out

orientdb> g.V('name', 'marko').out();

orientdb> g.V({name: 'marko'}).out();
gremlin>  g.v('9:1', '9:4').out('knows', 'created').in

orientdb> g.v('9:1', '9:4').out('knows', 'created').in();

orientdb> g.v(['9:1', '9:4']).out(['knows', 'created']).in(); 

Example 2: [i]

gremlin>  g.V[0].name

orientdb> g.V().index(0).property('name');

Example 3: [i..j]

gremlin>  g.V[0..<2].name

orientdb> g.V().range('0..<2').property('name');

Example 4: has

gremlin>  g.E.has('weight', T.gt, 0.5f).outV.transform{[it.id,it.age]}

orientdb> g.E().has('weight', 'T.gt', '0.5f').outV().transform('{[it.id,it.age]}');

Example 5: and & or

gremlin>  g.V.and(_().both("knows"), _().both("created"))

orientdb> g.V().and(g._().both("knows"), g._().both("created"))

gremlin>  g.v(1).outE.or(_().has('id', T.eq, "9:9"), _().has('weight', T.lt, 0.6f))

orientdb> g.v(1).outE().or(g._().has('id', 'T.eq', '9:9'), g._().has('weight', 'T.lt', '0.6f')); 

Example 6: groupBy

gremlin>    g.V.out.groupBy{it.name}{it.in}{it.unique().findAll{i -> i.age > 30}.name}.cap

orientdb>   g.V().out().groupBy('{it.name}{it.in}{it.unique().findAll{i -> i.age > 30}.name}').cap()

Example 7: retain

gremlin>  g.V.retain([g.v('9:1'), g.v('9:2'), g.v('9:3')])

orientdb> g.V().retain([g.v('9:1'), g.v('9:2'), g.v('9:3')])

Example 8: Create index

gremlin>  g.createIndex("my-index", Vertex.class)

orientdb> g.createIndex("my-index", "Vertex.class")

Example 9: Add to index

gremlin>  g.idx("my-index").put("name", "marko", g.v('9:1'))

orientdb> g.idx("my-index").put("name", "marko", g.v('9:1'))

Example 10: Retrieving indexed Element

gremlin>  g.idx("my-index")[[name:"marko"]]  

orientdb> g.idx("my-index", {name:"marko"});  

Example 11: Drop index

gremlin>  g.dropIndex("my-index", Vertex.class)

orientdb> g.dropIndex("my-index", "Vertex.class")

Executes SQL commands

orientdb.then(function(g) { 
  g.sql("select from V").then(function(res){console.log(res)});
}, function(err){console.log(err)});

Get a vertex

orientdb.then(function(g) { 
  g.v("9:400").then(function(res){console.log(res)});
}, function(err){console.log(err)});

Get vertex's out going vertices

orientdb.then(function(g) { 
  g.v("9:200").out().then(function(res){console.log(res)});
}, function(err){console.log(err)});

Configure error callback

The Promises API uses the then method to return results. then takes two parameters. The first is a function that returns a result. The second is a function that returns an error.

  g.sql("select from V").then(function(res){console.log(res)}, function(err){console.log(err)});

Create custom commands

addEdge = createCommand("CREATE EDGE <class> [CLUSTER <cluster>] FROM <from> TO <to> [CONTENT <content>]",
                      {  defaults:{ class: 'E' },
                         parameters:['from','to','content'] } );

As you can see it has parameters:

Parameter 1 is a SQL command "template". You basically write the sql command you want to pass to the server and the string is interpolated with the appropriate values. The values enclosed in < > get replaced. If it is also enclosed in [ ] then it is optional.

Parameter 2 takes an Object and is optional. It specifies a configuration for the method. The example above states that 'class' has a default of 'E', if no value exists for class this will be put in as the value. The parameters property specifies an argument list and order. The parameters is only used when and "object descriptor" isn't passed in as an argument (I'll explain that a little later)

Usage

Passing in a descriptor object

g.addEdge({cluster:'ACluster', from: 'can by ID or valid SQL', to: 'can by ID or valid SQL', content:{ aLabel:'someContent'}
});

Notice that the properties must match what was specified in the template.

OR based on the parameters specified above

g.addEdge('fromID','toID')

OR with content

g.addEdge('fromID','toID', {name:'contentName', prop2:'someMore'})

So what happens for addVertex which can have no arguments or have an object passed in as the first argument.

addVertex()

addVertex = createCommand("CREATE VERTEX [<class>] [CLUSTER <cluster>] [CONTENT <content>]",
                                        {  parameters:['content'] });

Here all values are optional. To use you just call g.addVertex() but if you pass in an object like

g.addVertex({name:'frank'})

then the Object passed in must not have any property that is the same as the template, i.e. class, cluster or content in this example and it must also have at least one parameters because the argument will be assigned to that value. I think to get around this the template could have values like <@class> and then when passed in you would use {'@class':'V'}

The reason I went this option is because you have a very involved API. This approach will offer the most flexibility with the ability to update and add new methods purely by writing one function.

For example to add a createClass method you would do the following

createClass = createCommand("CREATE CLASS <class> [EXTENDS <super>] [CLUSTER <clusterId>]");

then to use it you would call

g.createClass({class:'V2',super:'V',clusterId:[10, 12, 14]})