in s2core/src/main/scala/org/apache/s2graph/core/rest/RequestParser.scala [448:521]
private def parseQueryParam(labelGroup: JsValue, queryOption: QueryOption): Option[QueryParam] = {
for {
labelName <- parseOption[String](labelGroup, "label")
} yield {
val label = Label.findByName(labelName).getOrElse(throw BadQueryException(s"$labelName not found"))
val direction = parseOption[String](labelGroup, "direction").getOrElse("out")
val limit = {
parseOption[Int](labelGroup, "limit") match {
case None => defaultLimit
case Some(l) if l < 0 => hardLimit
case Some(l) if l >= 0 => Math.min(l, hardLimit)
}
}
val offset = parseOption[Int](labelGroup, "offset").getOrElse(0)
val interval = extractInterval(label, labelGroup)
val duration = extractDuration(label, labelGroup)
val scoring = extractScoring(label, labelGroup).getOrElse(Nil).toList
val exclude = parseOption[Boolean](labelGroup, "exclude").getOrElse(false)
val include = parseOption[Boolean](labelGroup, "include").getOrElse(false)
val hasFilter = extractHas(label, labelGroup)
val indexName = (labelGroup \ "index").asOpt[String].getOrElse(LabelIndex.DefaultName)
val whereClauseOpt = (labelGroup \ "where").asOpt[String]
val where = extractWhere(label, whereClauseOpt)
val includeDegree = (labelGroup \ "includeDegree").asOpt[Boolean].getOrElse(true)
val rpcTimeout = (labelGroup \ "rpcTimeout").asOpt[Int].getOrElse(DefaultRpcTimeout)
val maxAttempt = (labelGroup \ "maxAttempt").asOpt[Int].getOrElse(DefaultMaxAttempt)
val tgtVertexInnerIdOpt = (labelGroup \ "_to").asOpt[JsValue].filterNot(_ == JsNull).flatMap(jsValueToAny)
val cacheTTL = (labelGroup \ "cacheTTL").asOpt[Long].getOrElse(-1L)
val timeDecayFactor = (labelGroup \ "timeDecay").asOpt[JsObject].map { jsVal =>
val propName = (jsVal \ "propName").asOpt[String].getOrElse(LabelMeta.timestamp.name)
val propNameSeq = label.metaPropsInvMap.get(propName).getOrElse(LabelMeta.timestamp)
val initial = (jsVal \ "initial").asOpt[Double].getOrElse(1.0)
val decayRate = (jsVal \ "decayRate").asOpt[Double].getOrElse(0.1)
if (decayRate >= 1.0 || decayRate <= 0.0) throw new BadQueryException("decay rate should be 0.0 ~ 1.0")
val timeUnit = (jsVal \ "timeUnit").asOpt[Double].getOrElse(60 * 60 * 24.0)
TimeDecay(initial, decayRate, timeUnit, propNameSeq)
}
val threshold = (labelGroup \ "threshold").asOpt[Double].getOrElse(QueryParam.DefaultThreshold)
// TODO: refactor this. dirty
val duplicate = parseOption[String](labelGroup, "duplicate").map(s => DuplicatePolicy(s)).getOrElse(DuplicatePolicy.First)
val outputField = (labelGroup \ "outputField").asOpt[String].map(s => Json.arr(Json.arr(s)))
val transformer = (if (outputField.isDefined) outputField else (labelGroup \ "transform").asOpt[JsValue]) match {
case None => EdgeTransformer(EdgeTransformer.DefaultJson)
case Some(json) => EdgeTransformer(json)
}
val scorePropagateOp = (labelGroup \ "scorePropagateOp").asOpt[String].getOrElse("multiply")
val scorePropagateShrinkage = (labelGroup \ "scorePropagateShrinkage").asOpt[Long].getOrElse(500l)
val sample = (labelGroup \ "sample").asOpt[Int].getOrElse(-1)
val shouldNormalize = (labelGroup \ "normalize").asOpt[Boolean].getOrElse(false)
val cursorOpt = (labelGroup \ "cursor").asOpt[String]
// FIXME: Order of command matter
QueryParam(labelName = labelName,
direction = direction,
offset = offset,
limit = limit,
sample = sample,
maxAttempt = maxAttempt,
rpcTimeout = rpcTimeout,
cacheTTLInMillis = cacheTTL,
indexName = indexName, where = where, threshold = threshold,
rank = RankParam(scoring), intervalOpt = interval, durationOpt = duration,
exclude = exclude, include = include, has = hasFilter, duplicatePolicy = duplicate,
includeDegree = includeDegree, scorePropagateShrinkage = scorePropagateShrinkage,
scorePropagateOp = scorePropagateOp, shouldNormalize = shouldNormalize,
whereRawOpt = whereClauseOpt, cursorOpt = cursorOpt,
tgtVertexIdOpt = tgtVertexInnerIdOpt,
edgeTransformer = transformer, timeDecay = timeDecayFactor
)
}
}