繁体   English   中英

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

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

给出以下示例:

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);

我想从软件顶点lop和涟漪开始,找到所有创建lop和涟漪且年龄大于32的人。然后我要按人分组并在lop和涟漪上创建体重。

因此,我创建了一些可以给我带来结果的东西,但是看起来却很复杂:

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]]

另外,我希望最终结果具有与此类似的结构(对不起,如果我没有正确使用语法):

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

因此,我需要一个完整的人顶点及其所有内容以及所有导致垂落和波纹的边的列表。

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
        }]
    }
]

有趣的问题。 我认为更复杂的部分是转换为所需的形式,而不是实际的数据检索。 您的检索方法很好,尽管我这样写:

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]]

我认为这更容易阅读,因为很明显,您是从遍历路径中选择这些元素然后对它们进行操作,而不是使用遍历路径中的元素进行过滤。 但是,是否更好还值得商bat。 看到另一种获得此初始输出的方法并不令我感到惊讶,但这是我首先想到的。

真正的问题是如何将输出转换为您要求的预期形式,为此,我采用了这种方法:

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]]]

我只是使用project()将“人”顶点和边列表的展开Map转换为所需的结构。 请注意该project()的最终by() ,因为它需要其自己的嵌入式project()来处理原始Map值中展开的边列表。 关键是将fold()转换后的边放回List以便它们全部被考虑(否则by()将只处理第一个)。

您可以在Gremlin食谱中阅读有关集合操作的更多信息。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM