user3726393
user3726393

Reputation: 275

Converting Gremlin-Javascript Output into JSON

Is there a built-in way to convert the responses from Gremlin-Javascript into JSON? It appears the results are a Map or set of Maps depending on the traversal.

Right now we are just deeply checking the type and using Object.fromEntries if it is a Map.

Thanks!

Upvotes: 1

Views: 1120

Answers (2)

Jonathan Van Buren
Jonathan Van Buren

Reputation: 78

I am also struggling with this.

My current solution is to transform the structure:

normalizeData(gremlinData: Map<string, any>) {
    // Do this so that JSON.stringify works for maps
    (Map.prototype as any).toJSON = function () {
      return Object.fromEntries(this);
    };
    const mapStrippedData = JSON.parse(JSON.stringify(gremlinData));
    // Undo it so that we don't permanently pollute globals
    (Map.prototype as any).toJSON = undefined;

    return mapStrippedData;
  }

I really dislike this solution because it is slow. In my case, I am transforming a very large, deeply nested object, and having to JSON.stringify, and then JSON.parse the object is now the bottleneck for my API.

It would be great if you could configure gremlin to use a different serializer/deserializer that uses plain javascript objects instead of Maps...

Update 17/12/2020:

I ended up finding the solution above to be a bit slow due to it having to serialize and deserialize things so many times, so I resulted to monkey patching the Map serializer class for gremlin.

import { process, driver, structure } from 'gremlin';

// @ts-ignore
import { MapSerializer } from 'gremlin/lib/structure/io/type-serializers';

MapSerializer.prototype.deserialize = function (obj: any) {
  const value = obj['@value'];
  if (!Array.isArray(value)) {
    throw new Error('Expected Array, obtained: ' + value);
  }
  const result = {};
  for (let i = 0; i < value.length; i += 2) {
    // @ts-ignore
    result[`${this.reader.read(value[i])}`] = this.reader.read(value[i + 1]);
  }
  return result;
};

const { withOptions, t, P, column, order } = process;
export { driver, structure, withOptions, t, P, column, order, process };

Then I just import my gremlin methods from this file instead of directly from 'gremlin' and it just works.

Upvotes: 3

stephen mallette
stephen mallette

Reputation: 46216

Gremlin is designed to return container data structures like lists and maps/dictionaries. It does not return results as raw JSON. It can use JSON (i.e. GraphSON) for its serialization format but it will deserialize that form back to the complex objects of the programming language. You typically would not want to work with GraphSON directly as it has types embedded within it and is not convenient to work with in that fashion.

Upvotes: 0

Related Questions