Repository: incubator-s2graph
Updated Branches:
  refs/heads/master 3d941d654 -> 6d231e299


add queryParam


Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/d6c72ab8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/d6c72ab8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/d6c72ab8

Branch: refs/heads/master
Commit: d6c72ab838970724751cf8ea53cf90f1a587bc4a
Parents: 3d941d6
Author: daewon <[email protected]>
Authored: Fri Apr 6 13:17:32 2018 +0900
Committer: daewon <[email protected]>
Committed: Fri Apr 6 13:17:32 2018 +0900

----------------------------------------------------------------------
 .../scala/org/apache/s2graph/core/S2Edge.scala  | 108 ++++++++++---------
 .../org/apache/s2graph/core/S2EdgeBuilder.scala |   4 -
 .../org/apache/s2graph/core/S2EdgeLike.scala    |   4 -
 .../tall/SnapshotEdgeDeserializable.scala       |   5 +-
 .../s2graph/graphql/bind/Unmarshaller.scala     |  24 ++++-
 .../graphql/repository/GraphRepository.scala    |   6 +-
 .../apache/s2graph/graphql/types/S2Type.scala   |  23 +++-
 7 files changed, 100 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/d6c72ab8/s2core/src/main/scala/org/apache/s2graph/core/S2Edge.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/S2Edge.scala 
b/s2core/src/main/scala/org/apache/s2graph/core/S2Edge.scala
index 3323c4a..58b1ce1 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/S2Edge.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/S2Edge.scala
@@ -19,29 +19,21 @@
 
 package org.apache.s2graph.core
 
-import java.util
-import java.util.function.{BiConsumer, Consumer}
 
-import org.apache.s2graph.core.GraphExceptions.LabelNotExistException
 import org.apache.s2graph.core.S2Edge.{Props, State}
 import org.apache.s2graph.core.JSONParser._
 import org.apache.s2graph.core.mysqls.{Label, LabelIndex, LabelMeta, 
ServiceColumn}
 import org.apache.s2graph.core.types._
-import org.apache.s2graph.core.utils.logger
 import org.apache.s2graph.core.io.Conversions._
-import org.apache.tinkerpop.gremlin.structure
-import org.apache.tinkerpop.gremlin.structure.util.StringFactory
 import org.apache.tinkerpop.gremlin.structure.{Direction, Edge, Graph, 
Property, T, Vertex}
 import play.api.libs.json.{JsNumber, JsObject, Json}
 
 import scala.collection.JavaConverters._
-import scala.collection.mutable.{Map => MutableMap}
-import scala.concurrent.Await
 import scala.util.hashing.MurmurHash3
 
 object SnapshotEdge {
   def apply(e: S2EdgeLike): SnapshotEdge = {
-    val (smaller, larger) = (e.srcForVertexInner, e.tgtForVertexInner)
+    val (smaller, larger) = (srcForVertexInner(e), tgtForVertexInner(e))
 
     val snapshotEdge = SnapshotEdge(e.innerGraph, smaller, larger, 
e.innerLabel,
       GraphUtil.directions("out"), e.getOp(), e.getVersion(), 
e.getPropsWithTs(),
@@ -72,6 +64,29 @@ object SnapshotEdge {
 
     copy
   }
+
+  private def srcForVertexInner(e: S2EdgeLike): S2VertexLike = {
+    val belongLabelIds = Seq(e.getLabelId())
+    if (e.getDir() == GraphUtil.directions("in")) {
+      val tgtColumn = S2Edge.getServiceColumn(e.tgtVertex, 
e.innerLabel.tgtColumn)
+      e.innerGraph.elementBuilder.newVertex(VertexId(tgtColumn, 
e.tgtVertex.innerId), e.tgtVertex.ts, e.tgtVertex.props, belongLabelIds = 
belongLabelIds)
+    } else {
+      val srcColumn = S2Edge.getServiceColumn(e.srcVertex, 
e.innerLabel.srcColumn)
+      e.innerGraph.elementBuilder.newVertex(VertexId(srcColumn, 
e.srcVertex.innerId), e.srcVertex.ts, e.srcVertex.props, belongLabelIds = 
belongLabelIds)
+    }
+  }
+
+  private def tgtForVertexInner(e: S2EdgeLike): S2VertexLike = {
+    val belongLabelIds = Seq(e.getLabelId())
+    if (e.getDir() == GraphUtil.directions("in")) {
+      val srcColumn = S2Edge.getServiceColumn(e.srcVertex, 
e.innerLabel.srcColumn)
+      e.innerGraph.elementBuilder.newVertex(VertexId(srcColumn, 
e.srcVertex.innerId), e.srcVertex.ts, e.srcVertex.props, belongLabelIds = 
belongLabelIds)
+    } else {
+      val tgtColumn = S2Edge.getServiceColumn(e.tgtVertex, 
e.innerLabel.tgtColumn)
+      e.innerGraph.elementBuilder.newVertex(VertexId(tgtColumn, 
e.tgtVertex.innerId), e.tgtVertex.ts, e.tgtVertex.props, belongLabelIds = 
belongLabelIds)
+    }
+  }
+
 }
 
 case class SnapshotEdge(graph: S2GraphLike,
@@ -90,9 +105,9 @@ case class SnapshotEdge(graph: S2GraphLike,
   lazy val operation = GraphUtil.fromOp(op)
   lazy val edge = toEdge
   lazy val labelWithDir = LabelWithDirection(label.id.get, dir)
-//  if (!propsWithTs.contains(LabelMeta.timestamp.name)) throw new 
Exception("Timestamp is required.")
+  //  if (!propsWithTs.contains(LabelMeta.timestamp.name)) throw new 
Exception("Timestamp is required.")
 
-//  val label = Label.findById(labelWithDir.labelId)
+  //  val label = Label.findById(labelWithDir.labelId)
   lazy val schemaVer = label.schemaVersion
   lazy val ts = 
propsWithTs.get(LabelMeta.timestamp.name).innerVal.toString().toLong
 
@@ -101,7 +116,11 @@ case class SnapshotEdge(graph: S2GraphLike,
   def allPropsDeleted = S2Edge.allPropsDeleted(propsWithTs)
 
   def toEdge: S2EdgeLike = {
-    S2Edge(graph, srcVertex, tgtVertex, label, dir, op,
+    val e = S2Edge(graph, srcVertex, tgtVertex, label, dir, op,
+      version, propsWithTs, pendingEdgeOpt = pendingEdgeOpt,
+      statusCode = statusCode, lockTs = lockTs, tsInnerValOpt = tsInnerValOpt)
+
+    S2Edge(graph, e.srcForVertex, e.tgtForVertex, label, dir, op,
       version, propsWithTs, pendingEdgeOpt = pendingEdgeOpt,
       statusCode = statusCode, lockTs = lockTs, tsInnerValOpt = tsInnerValOpt)
   }
@@ -137,6 +156,7 @@ case class SnapshotEdge(graph: S2GraphLike,
     propsWithTs.put(key, newProps)
     newProps
   }
+
   override def hashCode(): Int = {
     MurmurHash3.stringHash(srcVertex.innerId + "," + labelWithDir + "," + 
tgtVertex.innerId)
   }
@@ -187,8 +207,8 @@ case class IndexEdge(graph: S2GraphLike,
                      version: Long,
                      labelIndexSeq: Byte,
                      private val propsWithTs: Props,
-                     tsInnerValOpt: Option[InnerValLike] = None)  {
-//  if (!props.contains(LabelMeta.timeStampSeq)) throw new 
Exception("Timestamp is required.")
+                     tsInnerValOpt: Option[InnerValLike] = None) {
+  //  if (!props.contains(LabelMeta.timeStampSeq)) throw new 
Exception("Timestamp is required.")
   //  assert(props.contains(LabelMeta.timeStampSeq))
   lazy val direction = GraphUtil.fromDirection(dir)
   lazy val operation = GraphUtil.fromOp(op)
@@ -222,7 +242,7 @@ case class IndexEdge(graph: S2GraphLike,
           * now we double store target vertex.innerId/srcVertex.innerId for 
easy development. later fix this to only store id once
           */
         val v = meta match {
-          case LabelMeta.timestamp=> InnerVal.withLong(version, schemaVer)
+          case LabelMeta.timestamp => InnerVal.withLong(version, schemaVer)
           case LabelMeta.to => toEdge.tgtVertex.innerId
           case LabelMeta.from => toEdge.srcVertex.innerId
           case LabelMeta.fromHash => indexOption.map { option =>
@@ -240,7 +260,7 @@ case class IndexEdge(graph: S2GraphLike,
   lazy val ordersKeyMap = orders.map { case (meta, _) => meta.name }.toSet
   lazy val metas = for ((meta, v) <- propsWithTs.asScala if 
!ordersKeyMap.contains(meta)) yield v.labelMeta -> v.innerVal
 
-//  lazy val propsWithTs = props.map { case (k, v) => k -> 
InnerValLikeWithTs(v, version) }
+  //  lazy val propsWithTs = props.map { case (k, v) => k -> 
InnerValLikeWithTs(v, version) }
 
   //TODO:
   //  lazy val kvs = 
Graph.client.indexedEdgeSerializer(this).toKeyValues.toList
@@ -266,7 +286,7 @@ case class IndexEdge(graph: S2GraphLike,
   }
 
   def property(labelMeta: LabelMeta): InnerValLikeWithTs = {
-//    
propsWithTs.get(labelMeta.name).map(_.innerValWithTs).getOrElse(label.metaPropsDefaultMapInner(labelMeta))
+    //    
propsWithTs.get(labelMeta.name).map(_.innerValWithTs).getOrElse(label.metaPropsDefaultMapInner(labelMeta))
     if (propsWithTs.containsKey(labelMeta.name)) {
       propsWithTs.get(labelMeta.name).innerValWithTs
     } else {
@@ -292,6 +312,7 @@ case class IndexEdge(graph: S2GraphLike,
     propsWithTs.put(key, newProps)
     newProps
   }
+
   override def hashCode(): Int = {
     MurmurHash3.stringHash(srcVertex.innerId + "," + labelWithDir + "," + 
tgtVertex.innerId + "," + labelIndexSeq)
   }
@@ -331,7 +352,6 @@ case class S2Edge(override val innerGraph: S2GraphLike,
   //  assert(propsWithTs.contains(LabelMeta.timeStampSeq))
 
 
-
   override def serviceName = innerLabel.serviceName
 
   override def queueKey = Seq(ts.toString, tgtVertex.serviceName).mkString("|")
@@ -346,10 +366,10 @@ case class S2Edge(override val innerGraph: S2GraphLike,
   //  }
 
 
-//  def toLogString: String = {
-//    //    val allPropsWithName = defaultPropsWithName ++ 
Json.toJson(propsWithName).asOpt[JsObject].getOrElse(Json.obj())
-//    List(ts, GraphUtil.fromOp(op), "e", srcVertex.innerId, 
tgtVertex.innerId, innerLabel.label, propsWithTs).mkString("\t")
-//  }
+  //  def toLogString: String = {
+  //    //    val allPropsWithName = defaultPropsWithName ++ 
Json.toJson(propsWithName).asOpt[JsObject].getOrElse(Json.obj())
+  //    List(ts, GraphUtil.fromOp(op), "e", srcVertex.innerId, 
tgtVertex.innerId, innerLabel.label, propsWithTs).mkString("\t")
+  //  }
 
   override def hashCode(): Int = {
     id().hashCode()
@@ -374,8 +394,10 @@ case class S2Edge(override val innerGraph: S2GraphLike,
   }
 
 }
+
 object EdgeId {
   val EdgeIdDelimiter = ","
+
   def fromString(s: String): EdgeId = {
     val js = Json.parse(s)
     s2EdgeIdReads.reads(Json.parse(s)).get
@@ -404,7 +426,6 @@ case class EdgeId(srcVertexId: VertexId,
   }
 
 
-
 }
 
 object EdgeMutate {
@@ -468,7 +489,9 @@ object S2Edge {
   type UpdateFunc = (Option[S2EdgeLike], S2EdgeLike, MergeState)
 
   def EmptyProps = new java.util.HashMap[String, S2Property[_]]
+
   def EmptyState = Map.empty[LabelMeta, InnerValLikeWithTs]
+
   def sameProps(base: Props, other: Props): Boolean = {
     if (base.size != other.size) false
     else {
@@ -494,12 +517,15 @@ object S2Edge {
       ret
     }
   }
+
   def fillPropsWithTs(snapshotEdge: SnapshotEdge, state: State): Unit = {
     state.foreach { case (k, v) => snapshotEdge.property(k.name, 
v.innerVal.value, v.ts) }
   }
+
   def fillPropsWithTs(indexEdge: IndexEdge, state: State): Unit = {
     state.foreach { case (k, v) => indexEdge.property(k.name, 
v.innerVal.value, v.ts) }
   }
+
   def fillPropsWithTs(edge: S2EdgeLike, state: State): Unit = {
     state.foreach { case (k, v) => edge.propertyInner(k.name, 
v.innerVal.value, v.ts) }
   }
@@ -531,9 +557,9 @@ object S2Edge {
     else {
       val lastDeletedAt = props.get(LabelMeta.lastDeletedAt.name).ts
       props.remove(LabelMeta.lastDeletedAt.name)
-//      val propsWithoutLastDeletedAt = props
-//
-//      propsWithoutLastDeletedAt.forall { case (_, v) => v.ts <= 
lastDeletedAt }
+      //      val propsWithoutLastDeletedAt = props
+      //
+      //      propsWithoutLastDeletedAt.forall { case (_, v) => v.ts <= 
lastDeletedAt }
       var ret = true
       val iter = props.entrySet().iterator()
       while (iter.hasNext && ret) {
@@ -557,8 +583,8 @@ object S2Edge {
     //            logger.debug(s"oldEdge: ${invertedEdge.map(_.toStringRaw)}")
     //            logger.debug(s"requestEdge: ${requestEdge.toStringRaw}")
     val oldPropsWithTs =
-      if (invertedEdge.isEmpty) Map.empty[LabelMeta, InnerValLikeWithTs]
-      else propsToState(invertedEdge.get.getPropsWithTs())
+    if (invertedEdge.isEmpty) Map.empty[LabelMeta, InnerValLikeWithTs]
+    else propsToState(invertedEdge.get.getPropsWithTs())
 
     val funcs = requestEdges.map { edge =>
       if (edge.getOp() == GraphUtil.operations("insert")) {
@@ -607,7 +633,7 @@ object S2Edge {
 
       //      logger.debug(s"${edgeMutate.toLogString}\n${propsWithTs}")
       //      logger.error(s"$propsWithTs")
-      val newEdge =requestEdge.copyEdgeWithState(propsWithTs)
+      val newEdge = requestEdge.copyEdgeWithState(propsWithTs)
 
       (newEdge, edgeMutate)
     }
@@ -807,8 +833,6 @@ object S2Edge {
     (propsWithTs, true)
   }
 
-//  def fromString(s: String): Option[Edge] = Graph.toEdge(s)
-
   def getServiceColumn(vertex: S2VertexLike, defaultServiceColumn: 
ServiceColumn) =
     if (vertex.id.column == ServiceColumn.Default) defaultServiceColumn else 
vertex.id.column
 
@@ -836,28 +860,6 @@ object S2Edge {
     e.innerGraph.elementBuilder.newVertex(VertexId(column, 
e.tgtVertex.innerId), e.tgtVertex.ts, e.tgtVertex.props, belongLabelIds = 
belongLabelIds)
   }
 
-  def srcForVertexInner(e: S2EdgeLike): S2VertexLike = {
-    val belongLabelIds = Seq(e.getLabelId())
-    if (e.getDir() == GraphUtil.directions("in")) {
-      val tgtColumn = getServiceColumn(e.tgtVertex, e.innerLabel.tgtColumn)
-      e.innerGraph.elementBuilder.newVertex(VertexId(tgtColumn, 
e.tgtVertex.innerId), e.tgtVertex.ts, e.tgtVertex.props, belongLabelIds = 
belongLabelIds)
-    } else {
-      val srcColumn = getServiceColumn(e.srcVertex, e.innerLabel.srcColumn)
-      e.innerGraph.elementBuilder.newVertex(VertexId(srcColumn, 
e.srcVertex.innerId), e.srcVertex.ts, e.srcVertex.props, belongLabelIds = 
belongLabelIds)
-    }
-  }
-
-  def tgtForVertexInner(e: S2EdgeLike): S2VertexLike = {
-    val belongLabelIds = Seq(e.getLabelId())
-    if (e.getDir() == GraphUtil.directions("in")) {
-      val srcColumn = getServiceColumn(e.srcVertex, e.innerLabel.srcColumn)
-      e.innerGraph.elementBuilder.newVertex(VertexId(srcColumn, 
e.srcVertex.innerId), e.srcVertex.ts, e.srcVertex.props, belongLabelIds = 
belongLabelIds)
-    } else {
-      val tgtColumn = getServiceColumn(e.tgtVertex, e.innerLabel.tgtColumn)
-      e.innerGraph.elementBuilder.newVertex(VertexId(tgtColumn, 
e.tgtVertex.innerId), e.tgtVertex.ts, e.tgtVertex.props, belongLabelIds = 
belongLabelIds)
-    }
-  }
-
   def serializePropsWithTs(edge: S2EdgeLike): Array[Byte] =
     
HBaseSerializable.propsToKeyValuesWithTs(edge.getPropsWithTs().asScala.map(kv 
=> kv._2.labelMeta.seq -> kv._2.innerValWithTs).toSeq)
 }

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/d6c72ab8/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeBuilder.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeBuilder.scala 
b/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeBuilder.scala
index 5e8d094..85321d3 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeBuilder.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeBuilder.scala
@@ -31,10 +31,6 @@ class S2EdgeBuilder(edge: S2EdgeLike) {
 
   def tgtForVertex = S2Edge.tgtForVertex(edge)
 
-  def srcForVertexInner = S2Edge.srcForVertexInner(edge)
-
-  def tgtForVertexInner = S2Edge.tgtForVertexInner(edge)
-
   def duplicateEdge = reverseSrcTgtEdge.reverseDirEdge
 
   def reverseDirEdge = copyEdge(dir = GraphUtil.toggleDir(edge.getDir))

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/d6c72ab8/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeLike.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeLike.scala 
b/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeLike.scala
index 3740f28..f2ea4ad 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeLike.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/S2EdgeLike.scala
@@ -123,10 +123,6 @@ trait S2EdgeLike extends Edge with GraphElement {
 
   def tgtForVertex = builder.tgtForVertex
 
-  def srcForVertexInner = builder.srcForVertexInner
-
-  def tgtForVertexInner = builder.tgtForVertexInner
-
   def duplicateEdge = builder.duplicateEdge
 
   def reverseDirEdge = builder.reverseDirEdge

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/d6c72ab8/s2core/src/main/scala/org/apache/s2graph/core/storage/serde/snapshotedge/tall/SnapshotEdgeDeserializable.scala
----------------------------------------------------------------------
diff --git 
a/s2core/src/main/scala/org/apache/s2graph/core/storage/serde/snapshotedge/tall/SnapshotEdgeDeserializable.scala
 
b/s2core/src/main/scala/org/apache/s2graph/core/storage/serde/snapshotedge/tall/SnapshotEdgeDeserializable.scala
index b7f5ba1..f5c10a7 100644
--- 
a/s2core/src/main/scala/org/apache/s2graph/core/storage/serde/snapshotedge/tall/SnapshotEdgeDeserializable.scala
+++ 
b/s2core/src/main/scala/org/apache/s2graph/core/storage/serde/snapshotedge/tall/SnapshotEdgeDeserializable.scala
@@ -26,6 +26,7 @@ import org.apache.s2graph.core.storage.CanSKeyValue
 import org.apache.s2graph.core.types._
 import org.apache.s2graph.core._
 import org.apache.s2graph.core.storage.serde.Deserializable
+import org.apache.s2graph.core.utils.logger
 
 class SnapshotEdgeDeserializable(graph: S2GraphLike) extends 
Deserializable[SnapshotEdge] {
   val builder = graph.elementBuilder
@@ -108,7 +109,9 @@ class SnapshotEdgeDeserializable(graph: S2GraphLike) 
extends Deserializable[Snap
         Option(snapshotEdge)
       }
     } catch {
-      case e: Exception => None
+      case e: Exception =>
+        logger.error("#" * 100, e)
+        None
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/d6c72ab8/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala
index 4308e2e..94c1e01 100644
--- 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala
@@ -20,8 +20,8 @@
 package org.apache.s2graph.graphql.bind
 
 import org.apache.s2graph.core.Management.JsonModel._
-import org.apache.s2graph.core.mysqls.ServiceColumn
-import org.apache.s2graph.core.{S2EdgeLike, S2VertexLike}
+import org.apache.s2graph.core.mysqls.{Label, ServiceColumn}
+import org.apache.s2graph.core.{QueryParam, S2EdgeLike, S2VertexLike}
 import org.apache.s2graph.graphql.repository.GraphRepository
 import org.apache.s2graph.graphql.types.S2Type._
 import sangria.marshalling._
@@ -125,11 +125,25 @@ object Unmarshaller {
     }
   }
 
-  def labelField(c: Context[GraphRepository, Any]): (S2VertexLike, String) = {
+  def labelField(label: Label, c: Context[GraphRepository, Any]): 
(S2VertexLike, QueryParam) = {
     val vertex = c.value.asInstanceOf[S2VertexLike]
-    val dir = c.arg[String]("direction")
 
-    (vertex, dir)
+    val dir = c.arg[String]("direction")
+    val offset = c.arg[Int]("offset") + 1 // +1 for skip degree edge: 
currently not support
+    val limit = c.arg[Int]("limit")
+    val whereClauseOpt = c.argOpt[String]("filter")
+    val where = c.ctx.parser.extractWhere(label, whereClauseOpt)
+
+    val qp = QueryParam(
+      labelName = label.label,
+      direction = dir,
+      offset = offset,
+      limit = limit,
+      whereRawOpt = whereClauseOpt,
+      where = where
+    )
+
+    (vertex, qp)
   }
 
   def serviceColumnFieldOnService(column: ServiceColumn, c: 
Context[GraphRepository, Any]): (Seq[S2VertexLike], Boolean) = {

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/d6c72ab8/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
index 626c0e6..078aefd 100644
--- 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
@@ -89,10 +89,8 @@ class GraphRepository(val graph: S2GraphLike) {
     graph.getVertices(vertex)
   }
 
-  def getEdges(vertex: S2VertexLike, label: Label, _dir: String): 
Future[Seq[S2EdgeLike]] = {
-    val dir = GraphUtil.directions(_dir)
-    val labelWithDir = LabelWithDirection(label.id.get, dir)
-    val step = Step(Seq(QueryParam(labelWithDir).copy(limit = 100, 
includeDegree = false)))
+  def getEdges(vertex: S2VertexLike, queryParam: QueryParam): 
Future[Seq[S2EdgeLike]] = {
+    val step = Step(Seq(queryParam))
     val q = Query(Seq(vertex), steps = Vector(step))
 
     graph.getEdges(q).map(_.edgeWithScores.map(_.edge))

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/d6c72ab8/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
index ca98df2..0fff21b 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
@@ -202,14 +202,31 @@ object S2Type {
       case "both" => Argument("direction", OptionInputType(BothDirectionType), 
"desc here", defaultValue = "out") :: Nil
     }
 
+    val idxNames = label.indices.map { idx =>
+      EnumValue(idx.name, value = idx.name)
+    }
+
+    val indexEnumType = EnumType(
+      s"Label_index_${label.label}",
+      description = Option("desc here"),
+      values = idxNames
+    )
+
+    val paramArgs = List(
+      Argument("offset", OptionInputType(IntType), "desc here", defaultValue = 
0),
+      Argument("limit", OptionInputType(IntType), "desc here", defaultValue = 
100),
+      Argument("index", OptionInputType(indexEnumType), "desc here"),
+      Argument("filter", OptionInputType(StringType), "desc here")
+    )
+
     lazy val edgeTypeField: Field[GraphRepository, Any] = Field(
       s"${label.label}",
       ListType(EdgeType),
-      arguments = dirArgs,
+      arguments = dirArgs ++ paramArgs,
       description = Some("fetch edges"),
       resolve = { c =>
-        val (vertex, dir) = Unmarshaller.labelField(c)
-        c.ctx.getEdges(vertex, label, dir)
+        val (vertex, queryParam) = Unmarshaller.labelField(label, c)
+        c.ctx.getEdges(vertex, queryParam)
       }
     )
 

Reply via email to