在ArangoDB AQL中,如何从图遍历中返回顶点和边?

5
我希望返回一个图遍历查询期间所有唯一的边和顶点列表。 这样可以给我想要的结果,但我需要执行两次相同的查询。
    LET eResults = (    
        FOR v,e
            IN 1..2
            ANY "entities/198593"
            relations
            OPTIONS { uniqueEdges: "path", bfs: true }
            RETURN DISTINCT KEEP(e, "_key", "_from", "_to", "type")
    )
    LET vResults = (
        FOR v,e
            IN 1..2
            ANY "entities/198593"
            relations
            OPTIONS { uniqueEdges: "path", bfs: true }
            RETURN DISTINCT KEEP(v, "_key", "name")
    )
    RETURN { edges: eResults, vertices: vResults}

查询结果包含每个边和顶点,且仅出现一次:
    [
      {
        "edges": [
          {
            "_from": "entities/198593",
            "_key": "391330",
            "_to": "entities/198603",
            "type": 300
          },
          {
            "_from": "entities/198593",
            "_key": "391390",
            "_to": "entities/198477",
            "type": 110
          },
          ...
        ],
        "vertices": [
          { "_key": "198603", "name": "A" },
          { "_key": "198477", "name": "B" },
          ...
        ]
      }
    ]

如何使用一条查询语句来实现相同的结果(唯一顶点和唯一边)?
PS:结果被包装在一个数组中,是否有什么想法可以解决这个问题?如何避免这种情况发生?
3个回答

3

你可以尝试两件事情,第一种是半个解决方案:

{uniqueEdges: "path", uniqueVertices: "global"} 

然而,我认为你需要删除“bfs:true”。

之后,在浏览器中需要使用javascript进行去重,或者如果您正在使用Foxx,则可以在API调用之前执行去重操作并返回结果。

但是,如果您正在使用Foxx,则可以在服务的index.js文件中使用以下JS。或者您可以直接在应用程序/网站等中使用uniqueList函数。这样你就会得到独一无二的列表。

  1. 创建一个函数,基于它们的_id属性获取唯一的对象数组

  2. 执行调用

  3. 调用之后,通过uniqueList函数运行结果,然后返回结果

例如:

function uniqueList(nonuniquelist){ 
    var u_list = []
    var u_edge_out_list = []
    //Go through each array and create unique set
    for(var w = 0; w < nonuniquelist.length; w++) {
        console.log()
        if (nonuniquelist[w] != null){
            if (u_list.indexOf(nonuniquelist[w]['_id']) <= 0){
                u_edge_out_list.push(nonuniquelist[w])
                console.log(nonuniquelist[w])
                u_list.push(nonuniquelist[w]['_id'])
                }
        }
    }
    return (u_edge_out_list);
}

router.get("/almost_unique_things",function(req,res){
   var bind_variables(entity_id: "entities/198593" );
   var aql = 
    `LET eResults = ( 
        FOR v,e
            IN 1..2
            ANY @entity_id
            relations
            OPTIONS { uniqueEdges: "path", bfs: true }
            RETURN DISTINCT KEEP(e, "_key", "_from", "_to", "type")
    )
    LET vResults = (
        FOR v,e
            IN 1..2
            ANY @entity_id"
            relations
            OPTIONS { uniqueEdges: "path", bfs: true }
            RETURN DISTINCT KEEP(v, "_key", "name")
    )
    RETURN { edges: eResults, vertices: vResults}`

    var results = db._query(aql,bind_variables).toArray();
    var uniqueEdges = uniqueList(edges);
    var uniqueVertices = uniqueList(vertices);
    RETURN { edges: uniqueEdges , vertices: uniqueVertices }
 });

1

你已经接近了...

通过FOR v,e这一行,你可以访问另外一个变量p

试试这个:

    FOR v,e,p
        IN 1..2
        ANY "entities/198593"
        relations
        OPTIONS { uniqueEdges: "path", bfs: true }
        RETURN DISTINCT p

编辑:如果您想删除重复的路径,可以使用RETURN DISTINCT p,但是如果您使用了uniqueEdges: "path",我不确定如何获得重复的路径。

看看这是否有帮助,如果没有,请回复我们,我们会尽力解决问题。


1
谢谢,但是p的问题是它会发送重复的节点和边。结果在一个不使用KEEP()的示例中,将产生1600行JSON而不是200行。如何消除这些重复的边和顶点? - now

1
//Starting from the path result above:
    let path =(FOR v,e,p
            IN 1..2
            ANY "entities/198593"
            relations
            OPTIONS { uniqueEdges: "path", bfs: true }
            RETURN DISTINCT p)
    
//compress, flatten and return first record out of array result the unique //vertices and edges:
          let vertices = first(return unique(flatten(path[**].vertices)))
          let edges = first(return unique(flatten(path[**].edges)))

//combine into a single graph object & return (as you've done above): 
    return {"vertices":vertices, "edges":edges}

对我来说,这是一个过于复杂的练习,对于一个图形数据库来说,这是一个显而易见的请求。我不评论上一个答案中添加的选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接