Gremlin Query -> mask id with custom entityId field

129 views
Skip to first unread message

Harshit Sharma

unread,
Feb 1, 2022, 9:27:50 AM2/1/22
to Gremlin-users
Hi Team,

I want to mask the Id field generated by graph DB (Janusgraph) with my custom filed entityId.
For example - Querying g.V(id) should resolve to g.V().has(entityId, id).

Is there a way we can do so?

Stephen Mallette

unread,
Feb 2, 2022, 10:59:24 AM2/2/22
to gremli...@googlegroups.com
You could create a DSL step for that.


You could also write a strategy maybe that extracted the id from the GraphStep and injected a has() step...i think that would work anyway.

--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/ef2acaea-53a1-4717-940c-873f15b89cc6n%40googlegroups.com.

Harshit Sharma

unread,
Feb 3, 2022, 8:53:03 AM2/3/22
to Gremlin-users
How can I write a strategy to replace g.V("123") with g.V().has("entityId", "123")

Stephen Mallette

unread,
Feb 3, 2022, 8:58:38 AM2/3/22
to gremli...@googlegroups.com
You would have to get familiar with strategy writing in general:


and maybe the best way to do that is to look at what some existing strategies are doing to get some inspiration:


I would probably look at JanusGraph strategies as well. Basically your strategy would look for a GraphStep, remove the ids and then transform the traversal to include your has() representation instead.



Harshit Sharma

unread,
Feb 3, 2022, 10:49:05 AM2/3/22
to Gremlin-users
Also for DSL, I have created a class GraphServiceTraversalSourceDsl which extends GraphTraversalSource
and an interface GraphServiceTraversalDsl extending GraphTraversal.Admin but not sure how to use the traversal?



@GremlinDsl(TraversalSource = "com.graph.gremlin.GraphServiceTraversalSourceDsl")
   public interface  GraphServiceTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
}




public class GraphServiceTraversalSourceDsl extends GraphTraversalSource {
    public GraphServiceTraversalSourceDsl(Graph graph, TraversalStrategies traversalStrategies) {
       super(graph, traversalStrategies);
   } 
    public GraphServiceTraversalSourceDsl(Graph graph) {
       super(graph);
   } 
    public GraphServiceTraversalSourceDsl(RemoteConnection connection) {
       super(connection);
   } 
   public GraphTraversal<Vertex, Vertex> V(String id) {
       GraphTraversalSource clone = this.clone();
clone.getBytecode().addStep(GraphTraversal.Symbols.V); GraphTraversal<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(clone); traversal.asAdmin().addStep(new GraphStep<>(traversal.asAdmin(), Vertex.class, true)); traversal = traversal.V(); if (id.length > 0) traversal = traversal.has("entityId", id); return traversal;

Stephen Mallette

unread,
Feb 4, 2022, 9:13:28 AM2/4/22
to gremli...@googlegroups.com
It's explained how to use it in the DSL documentation:


but basically it just looks like any other instantiation of "g" except that you specify your DSL traversal source:

SocialTraversalSource g = traversal(SocialTraversalSource.class).withEmbedded(graph);





Harshit Sharma

unread,
Feb 8, 2022, 12:58:35 PM2/8/22
to Gremlin-users
I'm trying to create a strategy like this - 

public final class HasStepStrategy extends AbstractTraversalStrategy<TraversalStrategy.ProviderOptimizationStrategy> implements TraversalStrategy.ProviderOptimizationStrategy {

    private static final HasStepStrategy INSTANCE = new HasStepStrategy();

    private HasStepStrategy() {
    }

    @Override
    public void apply(final Traversal.Admin<?, ?> traversal) {
            final HasStep<?, ?> HasStep = new HasStep<>(originalGraphStep);
            if (currentStep instanceof GraphStep) {
                TraversalHelper.replaceStep(originalGraphStep, HasStep, traversal);
            }
    }

    public static TinkerGraphStepStrategy instance() {
        return INSTANCE;
    }
}

my syntax may not be correct, and I'm not sure how to specify that replace g.V("id") with g.V().has("graph", "id")

Stephen Mallette

unread,
Feb 8, 2022, 8:28:12 PM2/8/22
to gremli...@googlegroups.com
GraphStep has this method: Object[] getIds() - i think you should be able to use that to pull the ids passed to V(...)



Harshit Sharma

unread,
Feb 9, 2022, 12:32:32 AM2/9/22
to Gremlin-users

I have created the following strategy

HasStepStretegy.java



public final class HasStepStrategy extends AbstractTraversalStrategy<TraversalStrategy.ProviderOptimizationStrategy> implements TraversalStrategy.ProviderOptimizationStrategy {

    private static final HasStepStrategy INSTANCE = new HasStepStrategy();

    private HasStepStrategy() {
    }

    @Override
    public void apply(final Traversal.Admin<?, ?> traversal) {
            if (traversal.getStartStep instanceOf GraphStep) {
            final GraphStep graphStep = (GraphStep) traversal.getStartStep();
           HasStep hasStep = HasStep(traversal, new HasContainer("graphId", P.within(Arrays.asList(graphStep.getIds())));
           TraversalHelper.replaceStep(hasStep, graphStep, traversal);
            graphStep.clearIds();

         }
    }

    public static TinkerGraphStepStrategy instance() {
        return INSTANCE;
    }
}


I have a HttpGremlinEndpointHandlerCustom.java there I have a method createBindings();

there I'm trying to call my HasStepStretegy

TraversalSource g2;
TraversalSource g = is.graphManager.getTraversal("g");
g2=.g.withStrategies(HasStepStrategy.instance().apply(  ????  ))


Now this asStepStrategy.instance().apply() require Traversal.Admin as an input so how can i get that?
Also is this the right way to call this HasStepStrategy?
Can u please review my Strategy and let me know if there is anything wrong or missing? 

Harshit Sharma

unread,
Feb 11, 2022, 1:06:09 PM2/11/22
to Gremlin-users
How can i get Traversal.Admin ?

Harshit Sharma

unread,
Feb 14, 2022, 9:56:20 AM2/14/22
to Gremlin-users
Hi,
thanks, Using Strategy i'm able to transform g.V(id)  to g.V().has("entityId", id)
But is there a way i can remove id from output as well or replace it with entityId?

Stephen Mallette

unread,
Feb 14, 2022, 3:13:55 PM2/14/22
to gremli...@googlegroups.com
If you return a Vertex then its going to return the id in the Vertex. i don't think there is a way around that. the id is the id. i dont think there is a way around that short of wholly new serializers that understood your datamodel to change out the id. of course, messing with that id even in serializers might cause unforeseen issues in Gremlin usage. if you need a user supplied id that badly, you probably should use a graph that actually support that feature.

Harshit Sharma

unread,
Feb 15, 2022, 11:43:05 PM2/15/22
to Gremlin-users
Actually, There are 2 Ids one is generated by graph database let's say id, and the other is created by our application let say entityId. Now I want my client to use only entityId, not id. If the client queries g.V(id) then it should get transformed to g.V().has("entityId", id) and in output also they should see entityId, not Id.

Harshit Sharma

unread,
Feb 16, 2022, 3:14:02 AM2/16/22
to Gremlin-users
how can i override termination steps of gremlin in my DSL like next(), toList(), map()?
Will you please help me with an example?

Stephen Mallette

unread,
Feb 16, 2022, 6:30:42 AM2/16/22
to gremli...@googlegroups.com
> Actually, There are 2 Ids one is generated by graph database let's say id, and the other is created by our application let say entityId. Now I want my client to use only entityId, not id. If the client queries g.V(id) then it should get transformed to g.V().has("entityId", id) and in output also they should see entityId, not Id.

I understand that and my last reply still holds for that situation. You would have to heavily modify how TinkerPop and your graph work to make something like that happen and there are no extension points for making it happen except for custom serializers that override element serialization (and as i said earlier...not sure that will even work)..

> how can i override termination steps of gremlin in my DSL like next(), toList(), map()?
Will you please help me with an example?

i've never done that and DSLs as we've documented them to be used aren't meant for such heavy purpose. like the idea of writing custom serializers, taking this approach might work, but you are really not working within the constructs of known TinkerPop extension points. You are now just extending classes and overriding default functionality which can be fine, but you will need to study the code base to do so. 

If you want to override termination steps then it might make sense to build your own extension of GraphTraversal and maintain it yourself rather than use our DSL constructs. Then just override the methods as you would in any Java code. 


Harshit Sharma

unread,
Feb 16, 2022, 8:36:37 AM2/16/22
to Gremlin-users
Thanks, I have created GraphServiceTraversalSourceDsl as mentioned below,
Configure it like this - 

GraphServiceTraversalSourceDsl graphServiceTraversalSourceDsl = new GraphServiceTraversalSourceDsl(graphManager.getAsBindings().get("graph"));
graphManager.putTraversalSource("g");
TraversaSource g2 = this.graphManager.getTraversalSource("g");
bindings.put("g", g2);


--------------------  GraphServiceTraversalDsl ------------------------------------
@GremlinDsl(TraversalSource = "com.graph.gremlin.GraphServiceTraversalSourceDsl")
   public interface  GraphServiceTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
}
------------------ GraphServiceTraversalSourceDsl -------------------------
public class GraphServiceTraversalSourceDsl extends GraphTraversalSource {
    public GraphServiceTraversalSourceDsl(Graph graph, TraversalStrategies traversalStrategies) {
       super(graph, traversalStrategies);
   } 
    public GraphServiceTraversalSourceDsl(Graph graph) {
       super(graph);
   } 
    public GraphServiceTraversalSourceDsl(RemoteConnection connection) {
       super(connection);
   } 
   public GraphTraversal<Vertex, Vertex> V(String id) {
       GraphTraversalSource clone = this.clone();
clone.getBytecode().addStep(GraphTraversal.Symbols.V); GraphTraversal<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(clone); traversal.asAdmin().addStep(new GraphStep<>(traversal.asAdmin(), Vertex.class, true)); traversal = traversal.V(); if (id.length > 0) traversal = traversal.has("entityId", id); return traversal;
   }
}

But still, when I'm doing a gremlin query it is pointing to DefaultGraphTraversal
Reply all
Reply to author
Forward
0 new messages