2015-12-08 28 views
0

我正在使用orientdb v2.1.4 是否有可能在SQL或Java API中使用while條件和maxdepth參數從目標記錄執行orientdb遍歷?例如:在orientdb遍歷中使用maxdepth和while

traverse all() from TargetRecordID maxdepth 25 while @class <> 'some_edge_class' 

orientdb分析器似乎應用maxdepth條件並忽略while條件。

我使用while條件,因爲我總體上有10個不同的邊緣類,但我希望做遍歷,同時排除邊緣類的子集(〜3)。如果您在遍歷期間使用了另一種方法來忽略某些邊緣類,那也會很好。

+0

這似乎是一個錯誤,你應該在http://orientdb.com/docs/2.1/SQL-Traverse文件中正式發行跟蹤 –

+0

頁面的問題.html表示給定的查詢在語法上是正確的,所以2.1.7(或至少我使用的版本)顯然是不足的。然而,似乎可行的解決方法是在WHILE條件中包含對$ depth的約束(例如'WHILE ...和$ depth <= 25'),而不是使用MAXDEPTH。 – peak

+0

@LuigiD謝謝,會做 – kfresh

回答

0

嘗試此查詢:

traverse both() from YourClass while both('your_edge_class').size() = 0 and $depth <= 25 

所以導線不會將連接到邊緣頂點/你指定的邊緣

編輯:

考慮下面的圖形示例,假設您不希望邊緣type1type2,您想要將節點1,2,3,4,5和8連接到邊緣type 3還是要避免所有頂點也連接到type 1type 2

enter image description here

編輯:

您可以使用此javascript函數有三個參數(RID,MAXDEPTH,excludeEdges)

var g=orient.getGraph(); 
var result=[]; 
var current=[]; 
var next=[]; 
var listEdges=excludeEdges.substring(1,excludeEdges.length-1).split(","); 
var root=g.command('sql','select from '+rid); 
current.push(root[0]); 
var step=1; 
while(current.length>0 && step<=maxDepth){ 
    for(i=0;i<current.length;i++){ 
     getVertex(current[i],"OUT"); 
     getVertex(current[i],"IN"); 
    } 
    change(); 
    step++; 
} 
return result; 

function change(){ 
    current=[]; 
    for (index=0;index<next.length;index++) 
     current.push(next[index]); 
    next=[]; 
} 

function getVertex(start,direction){ 
    var edgeDir="outE()"; 
    var reverseDirection="in"; 
    if(direction=="IN"){ 
     edgeDir="inE()"; 
     reverseDirection="out"; 
    } 
    var edges=g.command("sql","select expand("+edgeDir +") from "+start.getId()); 
    for(h=0;h<edges.length;h++){ 
     var found=false; 
     for(m=0;m<listEdges.length;m++){ 
      if(edges[h].getProperty("@class")==listEdges[m]){ 
       found=true; 
       break; 
      } 
     } 
     if(found==false){ 
      var vertex=g.command("sql","select expand("+ reverseDirection + ") from " +edges[h].getId()); 
      for(j=0;j<result.length;j++){ 
       if(result[j].getId().toString().equals(vertex[0].getId().toString()) || 
        vertex[0].getId().toString().equals(rid)){ 
        found=true; 
        break; 
       } 
      } 
      if(found==false){ 
       result.push(vertex[0]); 
       next.push(vertex[0]); 
      } 
     } 
    } 
} 

使用以下命令

select expand(result) from (select myFunction("#9:1",25,"[type1,type2]") as result) 
+0

嘿@LucaS,感謝您的反饋。所以,我意識到我在我的問題上犯了一個小錯誤。我想從一個特定的記錄遍歷(我將在我的問題中編輯這個)。所以,在你上面的例子中:假設頂點2有'RID#1:2'。我想執行從#1:2到深度2的遍歷,忽略'type1'和'type2'邊緣,因此返回頂點1,3,5,4。 您認爲這個查詢會在你的榜樣? ('type1')。size()= 0和both('type2')。size()= 0和$ depth <= 2'都從#1:2遍歷兩個()。 – kfresh

+0

Hi kfresh,that如果條件不符合起始節點,則查詢不起作用。我找到了不同的方法來獲得你正在尋找的頂點。 1)要找到1,3,4,5,你可以使用TRAVERSE:'從#1中選擇expand($ a):2 let $ a =(遍歷('type3')from('in type' )('type3')。size()> 0和$ depth <2並且name <> $ current.name) order by name' – LucaS

+0

2)沒有TRAVERSE:'select expand() ('type3')。size()> 0和name <> $ parent.current.name) 展開節點' – LucaS

0

隨着Java Api

OrientGraph g=new OrientGraph("remote:localhost/yourDb"); 
Traverse traverse = new Traverse(g); 

List<String> listExcludeEdges=new ArrayList<String>(); 
listExcludeEdges.add("type1"); 
listExcludeEdges.add("type2"); 
int maxDepth=3; 
String id="#9:1"; 

Set<Vertex> vertex=traverse.get(id,maxDepth,listExcludeEdges); 
for(Vertex v:vertex){ 
    System.out.println(v.getId()); 
} 
g.shutdown(); 

類遍歷

import java.util.LinkedHashSet; 
import java.util.List; 
import java.util.Set; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

import com.tinkerpop.blueprints.Direction; 
import com.tinkerpop.blueprints.Edge; 
import com.tinkerpop.blueprints.Vertex; 
import com.tinkerpop.blueprints.impls.orient.OrientGraph; 

public class Traverse { 

    private Set<Vertex> listVertex = new LinkedHashSet<Vertex>(); 
    private OrientGraph g; 
    private int maxDepth; 
    private List<String> listExcludeEdges; 
    private Vertex root; 

    public Traverse(OrientGraph g) { 
     this.g = g; 
    } 

    public Set<Vertex> get(String id,int maxDepth,List<String> listExcludeEdges) { 
     this.maxDepth=maxDepth; 
     this.listExcludeEdges=listExcludeEdges; 
     if(checkClassOrRid(id)){ 
      if (getRoot(id)) 
       getChildren(1,this.root); 
     } 
     return this.listVertex; 
    } 

    private boolean checkClassOrRid(String id){ 
     Pattern pattern = Pattern.compile("^#[0-9]+:[0-9]+"); 
     Matcher matcher = pattern.matcher(id); 
     if (matcher.matches()) { 
      for (Vertex v : g.getVertices()) { 
       if (v.getId().toString().equals(id)) 
        return true; 
      } 
     } 
     return false; 
    } 

    protected boolean getRoot(String id) {  
     this.root = g.getVertex(id); 
     if(this.root!=null) 
      return true; 
     return false; 
    } 

    protected void getChildren(int step,Vertex from) { 
     if(step<=maxDepth){ 
      getVertex(Direction.OUT,from,step); 
      getVertex(Direction.IN,from,step); 
     } 
    } 

    private void getVertex(Direction direction,Vertex from,int step){ 
     Iterable<Edge> edges = from.getEdges(direction); 
     for(Edge e:edges){ 
      boolean found=false; 
      for(String s:this.listExcludeEdges){ 
       if(e.getProperty("@class").equals(s)) 
        found=true; 
      } 
      if(found==false){ 
       Vertex vertex=null; 
       if(direction==Direction.OUT) 
        vertex=e.getVertex(Direction.IN); 
       else 
        vertex=e.getVertex(Direction.OUT); 
       this.listVertex.add(vertex); 
       getChildren(step+1,vertex); 
      } 
     } 
    } 
}