TechnologyJuly 25, 2013

Developing a Domain Specific Language in Gremlin

Stephen Mallette
Stephen Mallette
Developing a Domain Specific Language in Gremlin
g.V.has('type','post')
g.V.has('type','post').out('child').loop(1){it.loops<25}{true}
m=[:]
g.V.has('type','post').out('child').loop(1){it.loops<25}{true}
   .path.groupBy(m){it[0].userName}{it}{it.collectMany{it}.unique()}.iterate()
gremlin> m
==>marko=[v[184476380], v[282106584], v[184550536], v[189966816]]
==>josh=[v[173318448], v[188571048]]
==>daniel=[v[186130596], v[308964172]]
...
==>stephen=[v[176281532], v[182440524], v[188572948], v[282049412]]
class S {
  public static final String EDGE_CHILD = "child"
  public static final String PROPERTY_POST_ID = "postId"
  public static final String PROPERTY_TYPE = "type"
  public static final String TYPE_POST = "post"
}
class Steps {
  def load() {
    // this method will call methods that will initialize each step definition.
    // from the Gremlin REPL or other code base that utilizes the steps, simply
    // call new Steps().load() to make the steps available. 
  }
}
class Steps {
  def load() {
    defineStepPost()
  }
  private def defineStepPost() {
    Gremlin.defineStep('post', [Vertex, Pipe], { _().has(S.PROPERTY_TYPE, S.TYPE_POST) })
  }
}
g.V.post
g.V.post.out('child').loop(1){it.loops<25}{true}
m=[:]
g.V.post.out('child').loop(1){it.loops<25}{true}
   .path.groupBy(m){it[0].userName}{it}{it.collectMany{it}.unique()}.iterate()
class Steps {
  public static final int CONTROL_MAX_DEPTH = 25
  def load() {   
    defineStepPost()
    defineStepPostTree()
    defineStepFlattenThread()
  }
  private def defineStepPost() {
    Gremlin.defineStep('post', [Vertex, Pipe], { _().has(S.PROPERTY_TYPE, S.TYPE_POST) })
  }
  private def defineStepPostTree() {
    Gremlin.defineStep('postTree', [Vertex, Pipe], { depth = CONTROL_MAX_DEPTH ->
            _().post.out(S.EDGE_CHILD).loop(1){it.loops<depth}{true} }) } private def defineStepFlattenThread() { // the addition of .transform{it[0]}.dedup to the end of this Gremlin statement // makes flattenThread a pure side-effect in that it converts the output back to // the original vertices passed in. Gremlin.defineStep('flattenThread', [Vertex, Pipe], { m, depth = CONTROL_MAX_DEPTH, keyOn = null ->
            _().postTree(depth).path.groupBy(m){keyOn == null ? it[0] : keyOn(it[0])}{it}
            {it.collectMany{it}.unique()}.transform{it[0]}.dedup
    })
  }
}
g.V.post
// traverses to the default depth of 25
g.V.postTree
// traverse to the assigned depth of 256
g.V.postTree(256)
m=[:];g.V.flattenThread(m).iterate()
// traverse to depth 256
m=[:];g.V.flattenThread(m, 256).iterate()
// traverse to depth 256, key the Map on the postId of the root vertex instead of the vertex itself
m=[:];g.V.flattenThread(m, 256, {it.getProperty(PROPERTY_POST_ID)}).iterate()
Discover more
Gremlin
Share

One-stop Data API for Production GenAI

Astra DB gives JavaScript developers a complete data API and out-of-the-box integrations that make it easier to build production RAG apps with high relevancy and low latency.