2016-09-17 38 views
-1

我在Python 3.4中使用了ArangoDb v3.0.7。arangosh vs arango中的ArangoDB圖形遍歷結果之間的區別http

我在arango shell和通過使用'POST/_api/traversal'(從python使用python-arango庫)調用遍歷器中運行圖遍歷。我爲兩個呼叫使用相同的參數/配置,並使用相同的用戶定義擴展器和訪問者功能。

雖然shell中的遍歷按預期工作,但通過http api調用的遍歷不會返回應該訪問的所有頂點,如由expander函數指定的。

在蟒/ HTTP側,我執行:

query_result = dl_graph.traverse(
     start_vertex=start_vertex, 
     strategy="dfs", 
     max_depth=8, 
     order="preorder", 
     vertex_uniqueness="global", 
     edge_uniqueness="global", 
     filter_func=None, 
     expander_func=expander, // string containing function body, see def below 
     visitor_func=visitor // string containing function body, see def below 
    ) 

當阿朗戈殼下運行,則配置是:

{ 
    "datasource" : { 
    "graph" : [ Graph kraken EdgeDefinitions: [ 
     "Owns: [Account] -> [Account, Building]", 
     "Services: [BSObject] -> [BSObject, SpatialObject]", 
     "Employs: [Account] -> [Account, User]", 
     "WorksIn: [Project, Role, Team, TeamMember, User] -> [Building, Project, SpatialO...", 
     "IsIn: [SpatialObject] -> [Building, SpatialObject]", 
     "AccessControl: [Project, Role, Team, TeamMember, User] -> [BSObject, Building, C...", 
     "Instantiation: [BSObject] -> [Class]", 
     "Supply: [BSObject] -> [BSObject, SpatialObject]", 
     "HasRole: [TeamMember, User] -> [Role]", 
     "Contracts: [Account] -> [Account, Contract, Service]", 
     "can_read: [Team] -> [message_exchange]", 
     "can_write: [Team] -> [message_exchange]", 
     "Context: [message_exchange] -> [BSObject, Building, SpatialObject]", 
     "has_authority_over: [Team] -> [Team]", 
     "Provides: [Contract, ContractSchedule, Role] -> [Service]", 
     "To: [Service] -> [Team]", 
     "Under: [Role] -> [Contract, ContractSchedule]", 
     "Leases: [Account] -> [Building, SpatialObject]", 
     "Partof: [ContractSchedule] -> [Contract]", 
     "Manages: [testA] -> [Account]" 
    ] VertexCollections: [ 
     "Contract", 
     "ContractSchedule", 
     "Group", 
     "Service", 
     "test1", 
     "testdialog", 
     "GraphViews", 
     "GraphViewPositions", 
     "testBuilding", 
     "test5", 
     "test6", 
     "test7", 
     "test10", 
     "test11", 
     "test123", 
     "test134567", 
     "testA" 
    ] ], 
    "getVertexId" : function (vertex) { ... }, 
    "getPeerVertex" : function (edge, vertex) { ... }, 
    "getInVertex" : function (edge) { ... }, 
    "getOutVertex" : function (edge) { ... }, 
    "getEdgeId" : function (edge) { ... }, 
    "getEdgeFrom" : function (edge) { ... }, 
    "getEdgeTo" : function (edge) { ... }, 
    "getLabel" : function (edge) { ... }, 
    "getAllEdges" : function (vertex) { ... }, 
    "getInEdges" : function (vertex) { ... }, 
    "getOutEdges" : function (vertex) { ... } 
    }, 
    "order" : 0, 
    "itemOrder" : 0, 
    "strategy" : 1, 
    "uniqueness" : { 
    "vertices" : 2, 
    "edges" : 2 
    }, 
    "visitor" : function (config, result, vertex, path, connected) { ... }, 
    "filter" : function maxDepthFilter (config, vertex, path) { ... }, 
    "expander" : function (config, vertex, path) { ... }, 
    "maxIterations" : 10000000, 
    "minDepth" : 0, 
    "maxDepth" : 8, 
    "buildVertices" : true, 
    "messages" : [ 
    "in edge, gedID:525147be-ebec-11e5-9e42-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:525147be-ebec-11e5-9e42-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:525147be-ebec-11e5-9e42-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:525147be-ebec-11e5-9e42-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:525147be-ebec-11e5-9e42-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca", 
    "in edge, gedID:cfa4fa2e-ef0e-11e5-8377-80193436fdca" 
    ] 
} 

注意 '消息' 陣列最後是由下面的擴展函數添加的。這是我嘗試在http api下運行時將某些診斷輸出返回給python客戶端。這種技術也只能在shell下運行。設置消息數組的原因是,當使用http api時,我找不到'require(「internal」)。print(...)'輸出的位置。

擴展器功能如下。關鍵部分是該函數將遍歷圖形,直到它到達gedID爲'30dd37a6-ec18-11e5-81b7-80193436fdca'的頂點。當訪問者函數接收到這個頂點時,它會創建一個從該頂點到該路徑的ID列表。

function (config, vertex, path) { 
if (!config.messages) config.messages = []; 

var connections = [ ]; 
if (vertex.gedID == '67a59b76-efc3-11e5-9c6f-80193436fdca' 
|| vertex.gedID == '2df65d4a-ef3f-11e5-b2f8-80193436fdca' 
|| vertex.gedID == 'eb529db8-453e-11e6-b430-80193436fdca' 
|| vertex.gedID == 'd38d7148-5ccd-11e6-b863-80193436fdca' 
|| vertex.gedID == 'e6dc9d00-5ccd-11e6-9362-80193436fdca') // follow out edges for these vertices only 
{ 
    config.datasource.getOutEdges(vertex).forEach(function (e) { 
    require("internal").print("vertex, name:" + vertex.name); 
    require("internal").print("out edge, gedID:" + e.gedID); 
    var toVertex = require("internal").db._document(e._to) 

    if (toVertex.gedID != 'c1da8df6-2731-11e6-9aba-80193436fdca'   //  Block traversal through this vertex 
    && (e.gedID != '525147be-ebec-11e5-9e42-80193436fdca' || e.Update == 'afd34490-ef35-11e5-b18e-80193436fdca')  // not equal to edges of this type, and update has the specified value 
    && !(vertex.gedID == '67a59b76-efc3-11e5-9c6f-80193436fdca' && toVertex.gedID == '67a59b76-efc3-11e5-9c6f-80193436fdca')) // ignore connections between vertices of this type 
    connections.push({vertex: toVertex, edge: e}); 
    }); 
} 
else 
{ 
    config.datasource.getInEdges(vertex).forEach(function (e) { 
    require("internal").print("vertex, name:" + vertex.name); 
    require("internal").print("in edge, gedID:" + e.gedID); 
    config.messages.push("in edge, gedID:" + e.gedID); 

    if (vertex.gedID != "30dd37a6-ec18-11e5-81b7-80193436fdca" // Terminating vertex 
    && e.gedID != '1605c270-269e-11e6-9b64-80193436fdca' // Avoid traversal in this direction 
    && e.gedID != 'a50f19d8-efdc-11e5-a5bf-80193436fdca' // Avoid traversal in this direction 
    && e.gedID != '8e327408-5e45-11e6-8c9a-80193436fdca') // Avoid traversal in this direction 
     connections.push({ vertex: require("internal").db._document(e._from), edge: e}); 
    }); 
    require("internal").print("messages:" + config.messages); 
} 
return connections; 
} 

訪問者函數爲:

function (config, result, vertex, path, connected) {  
    if (! result || ! result.visited) { 
    return; 
    } 

    require("internal").print("messages:" + config.messages); 

    if (!result.visited.pathVertices) {result.visited.pathVertices = []} 

    result.visited.messages = config.messages; 

    if (result.visited.vertices) { 
    result.visited.vertices.push(vertex); 
    } 

    if (result.visited.paths) { 
    if (vertex.gedID == "30dd37a6-ec18-11e5-81b7-80193436fdca") 
    { 
     for (var e = 0; e < path.edges.length; e++) 
     { 
     result.visited.paths.push(path.edges[e]._id) 
     } 
     for (var v = 0; v < path.vertices.length; v++) 
     { 
     result.visited.pathVertices.push(path.vertices[v]._id) 
     } 
    } 
    } 
} 

的目的是,當用id「30dd37a6-ec18-11e5-81b7-80193436fdca」頂點被找到時,pathVertices陣列填充了標識。

當在arango shell下運行時,最終的頂點('30dd37a6-ec18-11e5-81b7-80193436fdca')被傳遞給visitor函數,並且pathVertices數組被填充。但是,通過http api運行時,pathVertices數組返回爲空。

此外,'result.visited.vertices'數組包含在shell下運行時的最終頂點(30dd37a6-ec18-11e5-81b7-80193436fdca),但在使用http api運行時缺少此頂點。

有可能有更好的方法來做到這一點,我很歡迎這方面的投入,但這裏的關鍵問題是爲什麼arango shell和http api之間的遍歷方式有所不同(以及我能否將我缺少的vertex/pathVertices數組返回給python代碼)。

+1

Definitly to much code! [如何創建一個最小,完整和可驗證的示例](http://stackoverflow.com/help/mcve) – buhtz

+0

抱歉,但通常當我閱讀其他人的問題時,會要求他們輸入更多代碼,特別是配置。這也是重現問題所需的代碼。 – Phil

+0

我相信你可以讓它更小。 – buhtz

回答

-1

正如你可能已經知道arangosh以及Python驅動程序談論HTTP到arangodb。

因此,您可以使用wireshark輕鬆地比較兩者是如何調用遍歷的。

比較這兩個,你可能會給一個大大減少的信息集應該是不同的。

+0

不是答案。這是一條評論。 – buhtz

相關問題