遍历Arangodb图,边缘进行数组过滤

时间:2018-08-04 17:47:10

标签: arangodb aql

我在arangodb中有这张测试图

节点:

[  { "_key": "A", "name": "A", "sector": "a"},
{ "_key": "B", "name": "B", "sector": "a"},
{ "_key": "C1", "name": "C1", "sector": "c"},
{ "_key": "C2", "name": "C2", "sector": "c"},
{ "_key": "C3", "name": "C3", "sector": "c"},
{ "_key": "C4", "name": "C4", "sector": "c"},
{ "_key": "D1", "name": "D1", "sector": "d"},
{ "_key": "D2", "name": "D2", "sector": "d"},
{ "_key": "E1", "name": "E1", "sector": "e"},
{ "_key": "E2", "name": "E2", "sector": "e"},
{ "_key": "E3", "name": "E3", "sector": "e"}]

边缘:

[{ "_from": "V/A","_to": "V/D1", "cat": [{"c":1,"s":3}] },
{ "_from": "V/A","_to": "V/D2", "cat": [{"c":1,"s":1}] },
{ "_from": "V/B","_to": "V/D2", "cat": [{"c":2,"s":1}] },
{ "_from": "V/D1","_to": "V/E1", "cat": [{"c":1,"s":8}] }, 
{ "_from": "V/D1","_to": "V/E2", "cat": [{"c":1,"s":4}] },
{ "_from": "V/D2","_to": "V/E2", "cat": [{"c":1,"s":3},{"c":2,"s":4}] },
{ "_from": "V/D2","_to": "V/E3", "cat": [{"c":2,"s":4}] },
{ "_from": "V/C1","_to": "V/B", "cat": [{"c":2,"s":5}] },
{ "_from": "V/C1","_to": "V/A", "cat": [{"c":1,"s":6}] },
{ "_from": "V/C2","_to": "V/A", "cat": [{"c":1,"s":2}] },
{ "_from": "V/C3","_to": "V/A", "cat": [{"c":1,"s":1}] },
{ "_from": "V/C4","_to": "V/A", "cat": [{"c":1,"s":1}] },
{ "_from": "V/C4","_to": "V/B", "cat": [{"c":2,"s":2}] } ]

它是更大图的简化部分(几乎一千个节点,数千个边)。请注意,在此示例中,每个边缘都有一个属性“ cat”作为类别对象的数组。实际上,在实际数据集中,每个边缘都是一个或多个网络的一部分。有22个网络/类别。在此工作示例中,只有两个,1和2。每个边都是一个类别的一部分,但D2-> E3是这两个类别中唯一的一个边缘。

问题:我必须遍历图,方法是从给定的顶点开始,过滤/选择选定类别(实际数据中的网络)及其相关顶点的边线。当然,要避免循环和重复的顶点或边。

示例:从B开始并选择类别2,我需要返回以下集合: v:[B,D2,E2,E3,C1,C4]和 e:[{B-> D2,D2-> E2,D2-> E3,C1-> B,C4-> B]

在AQL中,我尝试了以下各种过滤器:

FOR v, e, p IN 0..3 any "nodes/D2" edges OPTIONS {bfs: true, uniqueVertices: 'global'}
  //Here, the filter for cat 2  ?
return p

什么都没做(当然,我是Arango的新手)。

问题1:如何构造过滤器?

问题2:如何像上面的示例一样格式化结果?更准确地说(每个数组中对象的顺序无关紧要):

[
  nodes: [{name:"B",sector:"a"}, {name:"D2",sector:"d"}, {name:"E2",sector:"e"}, ...]
  edges: [{source: "B", target: "D2", s:1}, {source: "D2", target: "E2", s:4}, ...]
]

感谢帮助。

1 个答案:

答案 0 :(得分:0)

1)为了过滤"c":2中的条目cat,对于路径(p.edges[*])的所有边,必须检查c属性是否为( .c数组(cat)的.cat[*])包含值[2]

因此,在访问子属性数组IN时,我们使用p.edges[*].cat[*].c运算符。

FILTER [2] IN p.edges[*].cat[*].c

2)return格式也可以通过访问以下子属性来调整:

return {'nodes':{'name':v.name,'sector':v.sector},'edges':{'source':e._from,'target':e._to, 's': e.cat[*].s}}

调整后的查询为:

FOR v, e, p IN 0..3 any "V/D2" edges
FILTER [2] IN p.edges[*].cat[*].c
return {'nodes':{'name':v.name,'sector':v.sector},'edges':{'source':e._from,'target':e._to, 's': e.cat[*].s}}