ルートの頂点に来る方法を知っている部分グラフがあります。しかし、その後私はそれを歩く必要があります。Javaドライバを使用したDSEグラフ、グラフをどのように歩くか(ツリーのような)
具体的には、「サブグラフを歩いてください」ということは、サブグラフのすべての葉に歩いて行かなければならないということです(サブグラフはツリーのようなものだからです)。頂点。
私の質問は、どのように最もパフォーマンスの高い方法で達成するのですか?
私は2つのソリューションについて考えることができます。
まず、session.executeGraph("g.V().has('id','1')").one()
ステートメントをたくさんグラフに入れて、すべての単一の頂点とエッジを取得し、それらの計算を行います。しかし、私はこの方法が非常に非効率だと思う。
または私は私は私はかなり確信しています
GraphNode node = session.executeGraph("g.V().has('id','1').repeat(outE().subgraph('sg').otherV()).cap('sg').path()").one();
Path path = node.asPath();
を得ることができますパスオブジェクトでは動作し、第二の溶液が好ましいですが、私はどのように歩くためにパスオブジェクトを使用する見当もつかない私が見ることができるのは、オブジェクトのフラットマップだけだからです。ここ
更新#1
は、例えば木の写真です。目標は、ノードAの「複合価値」が必要です。ルールは非常に単純です。ノード(ルートを除く)には値があります。エッジには重みがあります。私は重みに関するすべての値を合計しなければならない。子供が親を1人しか持たない限り、私は完全な価値を取ることができます。子供が複数の親を持っている場合、私は重み付けを考慮する必要があります。例えばツリーで、Bの合成値は 100 + (500 * 50/60) + 1000
であろうとの合成値ははcombined value of B plus value of C
( == 2156.67)であろう。したがって、頂点とエッジから計算のためのプロパティが必要です。
更新#2
ここに私の解決策があります。
実際の計算を行っている抽象的なTreeクラスを実装しました(モック実装もあるため)。
public abstract class Tree {
// String == item id
protected final Map<String, Item> items = new HashMap<>();
private final String rootItemId;
protected Tree(String rootItemId) {
this.rootItemId = rootItemId;
}
public void accumulateExpenses() {
accumulateExpenses(null, null);
}
private double accumulateExpenses(String itemId, String parentItemId) {
final Item item = itemId == null ? items.get(rootItemId) : items.get(itemId);
final double expense = item.getExpense();
double childExpenses = 0;
for (String childId : item.getChildIds()) {
childExpenses += accumulateExpenses(childId, item.getId());
}
// calculate the percentage in case the item has multiple parents
final double percentage = item.getPercentage(parentItemId);
final double accumulatedExpenses = percentage * (expense + childExpenses);
item.setAccumulatedExpense(accumulatedExpenses);
return accumulatedExpenses;
}
}
そして、スーパークラス(抽象的なツリー)のアイテムマップを埋め込むGraphTreeクラスを実装しました。
public class GraphTree extends Tree {
public GraphTree(GraphNode graphNode, String rootNodeId) {
super(rootNodeId);
final GraphNode vertices = graphNode.get("vertices");
final GraphNode edges = graphNode.get("edges");
for (int i = 0; i < vertices.size(); i++) {
final Vertex vertex = vertices.get(i).asVertex();
final Item item = Item.fromVertex(vertex);
super.items.put(item.getId(), item);
}
for (int i = 0; i < edges.size(); i++) {
final Edge edge = edges.get(i).asEdge();
final Relation relation = Relation.fromEdge(edge);
super.items.get(relation.getParentId()).getRelations().add(relation);
}
}
}
完全性のために、ここではItemクラスもあります。
public class Item {
private String id;
private double accumulatedExpense;
private final List<Relation> relations = new ArrayList<>();
private final Map<String, Expense> expenses = new HashMap<>();
public void setAccumulatedExpense(double accumulatedExpense) {
this.accumulatedExpense = accumulatedExpense;
}
public double getPercentage(String parentId) {
if (parentId == null) {
return 1;
}
double totalWeight = 1;
double weight = 1;
for (Relation relation : relations) {
if (Objects.equals(id, relation.getChildId())) {
totalWeight += relation.getWeight();
if (Objects.equals(parentId, relation.getParentId())) {
weight = relation.getWeight();
}
}
}
return weight/totalWeight;
}
public static Item fromVertex(Vertex vertex) {
final Item item = new Item();
item.setId(IdGenerator.generate(vertex));
return item;
}
public List<String> getChildIds() {
return relations.parallelStream()
.filter(relation -> Objects.equals(relation.getParentId(),id))
.map(Relation::getChildId)
.collect(Collectors.toList());
}
}
最初のサブグラフを取得するには、次のコードを使用しました。
final String statement = String.format("g.V('%s').repeat(outE().subgraph('sg').otherV()).cap('sg')", rootNodeId);
final GraphNode node = session.executeGraph(statement).one();
あなたは幅優先探索を行っていると考えることがありますか? [This](http://stackoverflow.com/a/17833088/1457059)はかなり気の利いたアプローチを示しています。 gremlinクエリをDSEグラフに渡すのは簡単です。 –
ありがとうございます。しかし、私が持っている問題は、グラフを取得する方法(2番目のクエリでうまくいく)ではなく、Javaドライバでどのように動作するかです。私が戻すのは、すべての頂点とエッジを含む平坦な 'Map'を持つ' GraphNode'です。だから私は頂点間の重要な関係をすべて失う。私が期待したのは、 'node.getOutEdges()。forEach(edge-> edge.getInVertices())'などのようなものです。だから私の主な問題は、Java Driverを適切に扱う方法です。私はグレムリンについてはかなり新しいですが、これまでのところ理解していると思いますが、期待通りにJavaに転送することはできません。 –
あなたが探している究極の結果は何ですか?パスが必要なのではなく、特定のプロパティだけが蓄積されるように思えます。 –