【问题标题】:In ArangoDB AQL, how to return both vertices and edges from a graph traversal?在 ArangoDB AQL 中,如何从图遍历中返回顶点和边?
【发布时间】:2019-04-12 20:31:53
【问题描述】:

我想返回在图遍历查询期间遇到的所有唯一边和所有唯一顶点的列表。 这给了我想要的结果,但我执行了两次相同的查询:

    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:结果被包装在一个数组中,知道为什么吗?如何避免这种情况?

【问题讨论】:

    标签: arangodb aql


    【解决方案1】:

    你可以尝试两件事,第一件事是半途而废:

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

    但是你需要删除 bfs: 我认为是的。

    在此之后,您需要在浏览器中的 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 }
     });
    

    【讨论】:

      【解决方案2】:

      你已经接近了……

      通过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",你会如何获得重复的路径。

      看看是否有帮助,如果没有帮助,请发表回复,我们会看看我们能做些什么。

      【讨论】:

      • 谢谢,但是 p 的问题在于它发送了重复的节点和边。结果是 1600 行 JSON,而不是在一个没有 KEEP() 的示例中为 200 行。如何对这些边和顶点进行去重?
      【解决方案3】:
      //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}
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多