grex - node module - use javascript to write Gremlin('ish') commands sent to Rexter

430 views
Skip to first unread message

Frank Panetta

unread,
Jan 6, 2013, 7:49:04 PM1/6/13
to gremli...@googlegroups.com
Hi Guys,

I've created a node module ('grex') that allows you to access Rexster using gremlin. Obviously due to the nature of javascript there are a few differences, but its pretty close. Grex is still in alpha and it hasn't been tested thoroughly as yet and documentation is rather thin at the moment (meaning there's none), but I will work on getting some out soon. Really looking for feedback at this stage.

Anyway to get started you will need to install and run Rexter. To install grex just type -> 'npm install grex', then you should be right to go. Then in your server file just require('grex')
i.e. g = require('grex')

Some examples of the syntax are

NB. Because it's javascript all methods need to have bracket -> '()' and anything that the javascript engine would complain about needs to be passed in as a String -> i.e. T.lt should be a string argument

g.V().out('knows')
NB. can pass in comma seperated arguments or an array of strings

g.v(1).out().ifThenElse('{it.name=='josh'}','{it.age}','{it.name}')
NB. Closures need to be passed in as String arguments

g.v(1).out().index(1)
g.v(1).out().range('1..3')

g.V().retain([g.v(1), g.v(2), g.v(3)])
NB. Whenever referencing graph nodes you need to reference the graph -> g.v(1)

g.v(1).outE().or(g._().has('id', 'T.eq', "9"), g._().has('weight', 'T.lt', '0.6f'))
NB. _ method needs to reference g and have ()'s. T.lt and 0.6f need to be passed in a strings

g.createVertex(20, { k1: 'val1', k2: 'val2', k3: 'val3' })
g.removeVertex(20, ['k1', 'k3']) -> deletes properties
g.removeVertex(20) -> deletes vertex
g.updateVertex(20, {k1:'newVal'})

Now these return a Promise so the get the records you need to do the following:
//GET methods
g.V().out('knows').get().then(function(res){console.log(res)}, function(err){console.log(err)};

//POST methods
g.createVertex(20, { k1: 'val1', k2: 'val2', k3: 'val3' }).commit().then(function(res){console.log(res)}, function(err){console.log(err)};

Anyway, let me know what you think.

Thanks
Frank


Stephen Mallette

unread,
Jan 7, 2013, 5:47:13 AM1/7/13
to gremli...@googlegroups.com
Neat translation, Frank. I like the way you approached that. I've
added a link to your project in the Rexster wiki:

https://github.com/tinkerpop/rexster/wiki

I'll look at it in more detail and let you know if i have any questions.

Thanks,

Stephen
> --
>
>

Frank Panetta

unread,
Jan 7, 2013, 6:07:37 AM1/7/13
to gremli...@googlegroups.com
g.createVertex(20, { k1: 'val1', k2: 'val2', k3: 'val3' });

g.commit().then(function(res){console.log(res)}, function(err){console.log(err)}; 

Frank Panetta

unread,
Jan 7, 2013, 6:12:14 AM1/7/13
to gremli...@googlegroups.com
Thanks Stephen, I hope other's like it and find it useful.

One thing that I forgot to mention is that this has a dependancy on the batch kibble for POST methods. I've modified my original post to reflect the correct way to create|update|delete a Vertex or Edge. Essentially you do all the creations, updates and deletes, then you call commit.

Anyway, hoping to get some documentation soon.

Frank

Frank Panetta

unread,
Jan 14, 2013, 6:54:39 PM1/14/13
to gremli...@googlegroups.com

Nathan Pensack-Rinehart

unread,
May 16, 2013, 2:34:24 PM5/16/13
to gremli...@googlegroups.com
I'm doing a grex query, and on the success function (the first function parameter of then), the JSON is a string. 

Is this just me?  Firebug shows the query sent to the server correctly, and correctly returns JSON.

Frank Panetta

unread,
May 16, 2013, 8:54:45 PM5/16/13
to gremli...@googlegroups.com
Hi Nathan,

Are you able to raise this in the grex repo, if you don't mind (Just use the issues register). The Gremlin-users group should be for gremlin related questions.
Happy to discuss this with you there.

Thanks
Frank

Nicolas Clairon

unread,
Jun 19, 2013, 9:33:07 AM6/19/13
to gremli...@googlegroups.com
Hi,

I am testing grex for a project and I have a couple of questions :

 * on the documentation, when you create a vertex or an edge, you seem to pass the id. What if you delegate the id creation to the db (here Titan) ? How do you get the returned id ? How can reference the new vertex in an edge if I don't know the id ?

 * I saw another project gremlin-node which is also maintain by you. What are the benefices of grex over gremlin-node ? Should I use grex or gremlin-node ?

Thanks for you great work !

N.

Frank Panetta

unread,
Jun 20, 2013, 8:00:39 AM6/20/13
to gremli...@googlegroups.com
Hi Nicolas,

It seems that the batch kibble doesn't return the id's of the newly created elements, so at this point you can't. However, you are right, you need to have a reference to the newly created vertices/edges. I'll take a look at this and make it happen.

With regard to which to use, gRex or gremlin-node, that depends on your needs and what's available to you. 

Use gRex if you are making calls from a browser, it uses the REST API. However you can also use it on Node if you desire. It needs a Rexster server to use it and is easier to set up then gremlin-node.

Use gremlin-node if you are writing a node app and don't need a to make calls from a browser, as this module only runs on Node. There's no need for a Rexster server, as it uses the java libraries but the set up is a little more complex and it requires Python 2.x.x

Frank

Frank Panetta

unread,
Jun 21, 2013, 12:02:05 PM6/21/13
to gremli...@googlegroups.com
Hi Nicholas,

I've modified gRex to allow id creation by the database and return the id's for newly created Vertices. You can reference these vertices in calls to addEdge like so:

var t1, t2;

t1 = g.addVertex({name:'Test1a'});
t2 = g.addVertex({name:'Test2a'});
g.addEdge(t1, t2, 'linked', {name:"ALabel"})

t1 = g.addVertex({name:'Test1b'});
t2 = g.addVertex({name:'Test2b'});
g.addEdge(t2, t1, 'linked', {name:"BLabel"})

g.commit().then(function(result){
    if (result) {
        if (result.success == false) {
            console.error("Failed to add vertices.");
        } else {
            console.log("Added new vertices successfully. -> ", result);            
        }
    }
}, function(err) {
    console.error(err)
}); 

This will return a JSON object with an array called newVertices.

eg. 
{ success: true,
  newVertices: 
   [ { name: 'Test1a', _id: '#8:334', _type: 'vertex' },
     { name: 'Test2a', _id: '#8:336', _type: 'vertex' },
     { name: 'Test1b', _id: '#8:335', _type: 'vertex' },
     { name: 'Test2b', _id: '#8:337', _type: 'vertex' } ] }

I haven't uploaded the source code to NPM as yet, as I need to do some testing, but I thought you might like to take it for a test run. You can find the source in the 1.1.9a branch of the repo.

Dmill

unread,
Jul 6, 2013, 7:26:37 AM7/6/13
to gremli...@googlegroups.com
Hi Frank,

I've been looking into doing something similar in php. The final goal being slightly different as i would like to allow users to "inject" queries inside queries, but I digress. I was hoping I could steal a bit of your insight.

The first thing Ive been wondering was, doesnt having closures passed as strings corrupt method signatures? If we were to have a method that could express itself in the following ways wouldnt that be a problem? :
(gremlin)
g.V.thing('something'){closurecode}
&
g.V.thing('something','else')

Technically from what I see, in grex you'd be passing two strings to thing() in both cases. Is this not an issue when it comes to expressing them differently in gremlin? How have you handled that case? Simple checking for curly braces?

Im curious about this because i would like my dev to allow developpers to add to method arguments and/or closures to php-gremlin scripts that have already been set but not translated), so it is very important not to have overlapping method signatures.

Thanks in advance.

Also if anyone has a link to a list of methods available as well as all their signatures that would be great. Id like to find a list that covers roughly what gremlindocs covers. I'll have another look in the wiki, Im sure I must've missed something obvious.

Message has been deleted

Frank Panetta

unread,
Jul 6, 2013, 9:14:50 AM7/6/13
to gremli...@googlegroups.com
Hi Dmill,

Yes, the scenario you describe has its challenges. So, in order to distinguish between a string and a "closure" I use regex which identifies a closure by testing for a beginning and ending curly brace (i.e. "{it.name=='josh'}{it.age}{it.name}"). Also, if a closure is passed as an argument, it will be the last one. 

here's the regex:

var closureRegex = /^\{.*\}$/;

And here's my function that I use whenever I want to test for a closure

function _isClosure(val) {
    return _isString(val) && closureRegex.test(val);   
}

The gRex library is simply a string manipulation tool that formats a string that is understandable by Rexster. So there's not much to it really.

Anyway, I hope this helps clarify what's happening in gRex.

Also you can find a link to the latest gremlin API at the bottom of the gremlin wiki.

Frank

Dylan Millikin

unread,
Jul 6, 2013, 7:01:18 PM7/6/13
to gremli...@googlegroups.com
Thanks a lot for the prompt reply.

Ok it makes sense that you would proceed this way rather than using, say, a lambda with a return. At least it's simple and easy to implement/read.
I've got another use case I've been thinking about and was wondering if you'd already had to handle it.

If I were to have these two gremlin method signatures:

g.V.thing('something', 'else', 'here');
&
g.V.thing('something', T.gt, 0.5f); //lazy example

Would you be able to differentiate them? I don't think there are any methods that would currently overlap in such a way but I was curious.
I've been thinking of just handling these on special case basis -if- they popped up. 

In any event, thanks a lot for taking the time to reply to these. It's been very helpful.

Dylan


2013/7/6 Frank Panetta <frank....@entrendipity.com.au>
Hi Dmill,

Yes, the scenario you describe has its challenges. So, in order to distinguish between a string and a "closure" I use regex which identifies a closure by testing for a beginning and ending curly brace (i.e. "{it.name=='josh'}{it.age}{it.name}"). Also, if a closure is passed as an argument, it will be the last one. 

here's the regex:

var closureRegex = /^\{.*\}$/;

And here's my function that I use whenever I want to test for a closure

function _isClosure(val) {
    return _isString(val) && closureRegex.test(val);   
}

The gRex library is simply a string manipulation tool that formats a string that is understandable by Rexster. So there's not much to it really.

Anyway, I hope this helps clarify what's happening in gRex.

Also you can find a link to the latest gremlin API at the bottom of the gremlin wiki.

Frank

All gRex does is transform/manipulate the methods and arguments into a string that Rexster understands, so taking in a 

On Saturday, 6 July 2013 21:26:37 UTC+10, Dmill wrote:

--
You received this message because you are subscribed to a topic in the Google Groups "Gremlin-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/gremlin-users/i8BYgNOZCkk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to gremlin-user...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Frank Panetta

unread,
Jul 6, 2013, 9:50:09 PM7/6/13
to gremli...@googlegroups.com
Hi Dylan,

Lets take this off-line :)

Frank

Nicolas Clairon

unread,
Jul 9, 2013, 5:39:12 AM7/9/13
to gremli...@googlegroups.com
Thanks Frank. I'm back from holiday and I'll give it a try.

If grex is using rexter, gremlin-node would be faster than grex and may be better with a lot of queries...

Frank Panetta

unread,
Jul 9, 2013, 5:43:15 AM7/9/13
to gremli...@googlegroups.com
No worries. Check it out. But just be aware that gRex is async via Promises, gremlin-node is sync.
Reply all
Reply to author
Forward
0 new messages