2016-04-15 10 views
2

Ich habe ein Diagramm, das wie folgt aussieht: graphWie sammle ich optionale Zweige in TinkerPop3?

gremlin-scala verwenden, ich versuche, von A zu überqueren und sammeln diese Tupel:

(A, Some(A1)), (B, None), (C, Some(A2))

So im Wesentlichen möchte ich immer wieder α nehmen zu out Kanten und optional Zweig β, sammeln diese outs. Ich vermute, dass ich einen leeren "Schritt" injizieren muss, wenn es keine β Kante gibt, aber ich bin nicht in der Lage gewesen, herauszufinden, wie man das macht.

Ich bin auch ein wenig verwirrt darüber, wie nach β jetzt zurückzuspulen durchqueren, dass jump wurde auf mysteriöse Weise entfernt worden ist (TP 3.1+)

Bisher habe ich so etwas wie:

graph.V("A").untilWithTraverser(t => t.get.outE(α).notExists() 
    ).repeat(_.out(α).as(foo).out(β).as(bar)).select((foo,bar)).toList 

Aber diese wird nicht zum Haupttravers zurückgespult und schlägt fehl, wenn Knoten im "Stamm" fehlen β out

Antwort

1

Dies ist meine gremlin-scala-Lösung, basierend auf Daniels Antwort.

val unionTraversal = __[(String, Vertex)].union(
    __[Vertex].identity.map("blob" -> _), 
    __.out(Beta).map("beta" -> _) 
).traversal 

def pathTuplesToScalaTuples(path: Path) = 
    path.objects.asScala.map(_.asInstanceOf[java.util.ArrayList[(String, Vertex)]].asScala.toList).toList 

val pathO = graph.V("A") 
    .until(_.not(_.out(Alpha))) 
    .repeat(_.out(Alpha)) 
    .path.by(unionTraversal.fold).headOption 
val tuples = pathO.map(pathTuplesToScalaTuples) 

Dies beinhaltet leider ein paar Kludges, um die emittierten Scheitelpunkte nützlich zu machen.

Zuerst werden Schrittbeschriftungen gelöscht, wenn ein anonymer Durchlauf an eine Union übergeben wird, sodass Sie Ihre ausgegebenen Mengen nicht mit .as("blob") beschriften können - dafür gibt es die Umgehungsmöglichkeit in Tupel mit Zeichenfolgenbeschriftungen.

Zweitens, Gremlin-Scala hat noch keinen Wrapper für Path (und kann es nie bekommen, weil Pfade beliebige Struktur haben können), so müssen wir eine hässliche hässliche Besetzung machen.

3

Ich kann keine gremlin-scala Lösung anbieten, aber es sollte einfach für Sie sein konvertieren die folgende Groovy Beispiel:

g.V("A").until(__.not(outE("alpha"))). 
      repeat(out("alpha")).path().by(union(identity(), out("beta")).fold()) 

Dies wird zurück:

[[A, A1], [B], [C, A2]] 

IMO dies ausreichend ist. wenn Sie einen einheitlichen Satz von 2 Einträge Allerdings müssen, könnten Sie so etwas tun:

g.V("A").until(__.not(outE("alpha"))).repeat(out("alpha")). 
    path().by(union(identity(), coalesce(out("beta"), constant("N/A"))).fold()) 

... die dann zurück:

[[A, A1], [B, N/A], [C, A2]] 

komplette Session:

http://gremlinbin.com/bin/view/57133bdc8ee00