graph-databases-in-action icon indicating copy to clipboard operation
graph-databases-in-action copied to clipboard

using Node.js driver - Server error: gremlin-javascript is not an available GremlinScriptEngine (599)

Open mattwelke opened this issue 5 years ago • 2 comments

I'm a MEAP reviewer. I'm following along and I'm on chapter 8 now, but by now I've decided to stop trying to create the Java app since I'm not very familiar with Java and struggled more with the details of setting up that app in IntelliJ IDEA than doing the actual programming. I decided to switch to Node.js since that's a daily driver language of mine. I've been able to get this working well so far, doing the less complex traversals in the book in my Node.js app. I had to dig through the Node.js library to learn that I had to import statics (conventionally imported as __ in the app itself) and use it for things like __.identity().

But, I ran into trouble with the second traversal in Chapter 8. My function looks like this. I use a similar approach to the example Java app that involves injecting the GraphTraversalSource object into the function:

const gremlin = require('gremlin');
const desc = gremlin.process.order.desc;
const __ = gremlin.process.statics;

async function getHighestRatedRestsNear(g, c, personId) {
    try {
        const rests = await g.V()
            .has('person', 'person_id', personId)
            .out('lives')
            .in_('within')
            .group()
            .by(__.identity())
            .by(__.in_('about').values('rating').mean())
            .unfold()
            .order()
            .by(__.values, desc)
            .limit(10)
            .project('restaurant_name', 'rating_average')
            .by(__.select(__.key).values('name'))
            .by(__.select(__.values))
            .toList();
        console.log(`Restaurants:`, rests);
    } catch (e) {
        console.log(`Error:`, e.message);
    }
    await c.close();
};

It results in the following console output:

Error: Server error: gremlin-javascript is not an available GremlinScriptEngine (599)

By commenting out bits of the traversal at a time, I determined that it works up until I add the .order().by(__.values, desc) part. This code:

const rests = await g.V()
    .has('person', 'person_id', personId)
    .out('lives')
    .in_('within')
    .group()
    .by(__.identity())
    .by(__.in_('about').values('rating').mean())
    .unfold().toList();
    // .order()
    // .by(__.values, desc)
    // .limit(10)
    // .project('restaurant_name', 'rating_average')
    // .by(__.select(__.key).values('name'))
    // .by(__.select(__.values))
    // .toList();

results in the following console output:

Restaurants: 
getHighestRatedRestsNear.js:24
Array(18) [Map(1), Map(1), Map(1), Map(1), Map(1), Map(1), Map(1), Map(1), …]

I googled the error message but wasn't able to find much. My guess so far is that it has to do with the setup of Gremlin Server according to the book not supporting the Node.js driver fully. Perhaps it only supports Groovy and Java as the book uses. What do you think about this? I don't mind following along only being able to run traversals in the Gremlin console, but I was finding it more interesting when I was able to follow along making an app I was able to understand well at the same time.

mattwelke avatar Jan 14 '20 03:01 mattwelke

I know this was a long time ago but the answer is __.values should be gremlin.process.column.values (an enum value, not the values function.

cuzzlor avatar Mar 28 '22 06:03 cuzzlor

Been a long time since I was working with this code, so I don't think I'll try again, but thanks for responding. :) That sounds about right, perhaps I imported the wrong thing, trying to make my code look like the Java code from the book.

mattwelke avatar Mar 30 '22 21:03 mattwelke