简体   繁体   English

TinkerPop / Graph:遍历边缘,然后按结果顶点和遍历的边缘分组

[英]TinkerPop/Graph: Traverse edge and then group by resulting vertex and traversed edge

Given the example below: 给出以下示例:

marko = graph.addVertex(label, "person", id, 1, "name", "marko", "age", 29);
vadas = graph.addVertex(label, "person", id, 2, "name", "vadas", "age", 27);
josh = graph.addVertex(label, "person", id, 4, "name", "josh", "age", 32);
peter = graph.addVertex(label, "person", id, 5, "name", "peter", "age", 35);
lop = graph.addVertex(label, "software", id, 6, "name", "lop", "lang", "java");
ripple = graph.addVertex(label, "software", id, 7, "name", "ripple", "lang", "java");
tripple = graph.addVertex(label, "software", id, 8, "name", "tripple", "lang", "java");

marko.addEdge("created", lop, id, 9, "weight", 0.4f);
josh.addEdge("created", ripple, id, 10, "weight", 1.0f);
josh.addEdge("created", lop, id, 11, "weight", 0.4f);
peter.addEdge("created", lop, id, 12, "weight", 0.2f);
peter.addEdge("created", tripple, id, 13, "weight", 0.2f);
vadas.addEdge("created", tripple, id, 14, "weight", 0.2f);

I want to start with software vertices lop and ripple, find all persons which created lop and ripple and which are older than 32. Then I want to group by person and the created weigth on lop and ripple. 我想从软件顶点lop和涟漪开始,找到所有创建lop和涟漪且年龄大于32的人。然后我要按人分组并在lop和涟漪上创建体重。

So I created something which gives me a result but it looks rather comlicated: 因此,我创建了一些可以给我带来结果的东西,但是看起来却很复杂:

g.V(6,7).as('soft').
in('created').has('age',gte(32)).
group()
by()
by(
  outE().where(
    inV().where(eq('soft'))
  ).fold())
.unfold()

==>v[4]=[e[11][4-created->6], e[10][4-created->7]]
==>v[5]=[e[12][5-created->6]]

Also, I want the end result to have a structure similar to this (sorry if I did not get the syntax right): 另外,我希望最终结果具有与此类似的结构(对不起,如果我没有正确使用语法):

==>v[4,person,josh,32]=[lop=0.4, ripple=1.0]
==>v[5,person,peter,35]=[lop=0.2]

So I need the complete person vertex with all its contents and a list of all edges which lead to lop and ripple. 因此,我需要一个完整的人顶点及其所有内容以及所有导致垂落和波纹的边的列表。

The json representation would look like: json表示形式如下:

[{
        "id": 4,
        "label": "person",
        "name": "josh",
        "age": "32",
        "software": [{
                "name": "lop",
                "weigth": 0.4
            },
            {
                "name": "ripple",
                "weigth": 1.0
            }
        ]
    },
    {
        "id": 5,
        "label": "person",
        "name": "peter",
        "age": "35",
        "software": [{
            "name": "lop",
            "weigth": 0.2
        }]
    }
]

Interesting question. 有趣的问题。 I think the more complex part is in the transformation to the form you want rather than the actual data retrieval. 我认为更复杂的部分是转换为所需的形式,而不是实际的数据检索。 Your approach to retrieval is fine, though I wrote it this way: 您的检索方法很好,尽管我这样写:

gremlin> g.V(6,7).
......1>   inE('created').as('e').outV().has('age',gte(32)).as('p').
......2>   group().
......3>    by(select('p')).
......4>    by(select('e').fold()).
......5>   unfold()
==>v[4]=[e[11][4-created->6], e[10][4-created->7]]
==>v[5]=[e[12][5-created->6]]

I think that's a little easier to read, because it's clear that you're selecting these elements from the traversal path and then operating on them rather than using elements from the traversal path for filtering. 我认为这更容易阅读,因为很明显,您是从遍历路径中选择这些元素然后对它们进行操作,而不是使用遍历路径中的元素进行过滤。 But, it's debatable whether or not it's better. 但是,是否更好还值得商bat。 It wouldn't surprise me to see another way to get this initial output, but that's what first came to mind for me. 看到另一种获得此初始输出的方法并不令我感到惊讶,但这是我首先想到的。

The real question is how to translate that output to the expected form you requested and for that I took this approach: 真正的问题是如何将输出转换为您要求的预期形式,为此,我采用了这种方法:

gremlin> g.V(6,7).
......1>   inE('created').as('e').outV().has('age',gte(32)).as('p').
......2>   group().
......3>    by(select('p')).
......4>    by(select('e').fold()).
......5>   unfold().
......6>   project('id','label','name','age','software').
......7>     by(select(keys).id()).
......8>     by(select(keys).label()).
......9>     by(select(keys).values('name')).
.....10>     by(select(keys).values('age')).
.....11>     by(select(values).
.....12>        unfold().
.....13>        project('name','weight'). 
.....14>          by(inV().values('name')).
.....15>          by('weight').
.....16>        fold())
==>[id:4,label:person,name:josh,age:32,software:[[name:lop,weight:0.4],[name:ripple,weight:1.0]]]
==>[id:5,label:person,name:peter,age:35,software:[[name:lop,weight:0.2]]]

I simply used project() to convert the unfolded Map of "person" vertex and edge list to the desired structure. 我只是使用project()将“人”顶点和边列表的展开Map转换为所需的结构。 Note the final by() of that project() in that it requires its own embedded project() to deal with the unfolded list of edges in the values of the original Map . 请注意该project()的最终by() ,因为它需要其自己的嵌入式project()来处理原始Map值中展开的边列表。 The key there is to fold() back those transformed edges into a List so that they are all accounted for (otherwise by() would only deal with the first). 关键是将fold()转换后的边放回List以便它们全部被考虑(否则by()将只处理第一个)。

You can read more about collection manipulation in Gremlin Recipes . 您可以在Gremlin食谱中阅读有关集合操作的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Gremlin / tinkerpop:在遍历的每个顶点和边中插入 key:value 属性常量,然后返回路径 - Gremlin / tinkerpop: insert key:value property constant in every vertex and edge traversed then return path 打印图形顶点和边缘源/目标 - JGraphT - printing graph vertex and edge source/target - JGraphT 获取两个图顶点之间的边列表 - Get Edge list between two graph Vertex 基于边的属性值遍历图 | 小精灵 - Traverse through graph based on edge's properties values | Gremlin 给定一个邻接图和多次遍历,优化查找最遍历的边的方法 - Optimizing a method to find the most traversed edge given an adjacency graph and several traversals 如何遍历图形并在提升过程中提取边缘权重? - How to traverse a graph and extract edge weights along the way with boost? 以最少的游程遍历网格(图形)的每个边缘 - Traverse every edge of a grid (graph) with least number of runs 在删除图中连接到源顶点的边时获得额外的边 - getting extra edge when removing the edges connected to the source vertex in a graph 如何使用 Gremlin 检查图形中是否存在节点/顶点/边 - How to check the node/vertex/Edge is present in the Graph using Gremlin 图形数据从边输入格式转换为顶点输入格式 - Conversion of graph data from Edge Input Format to Vertex Input Format
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM