gremlin - 对来自不同顶点的属性进行分组

标签 gremlin

我有一个看起来像下面这样的图表:

pathway -> pathway_component -> gene -> organism

您可以像这样制作示例图:

m1 = g.addV('pathway').property('pathway_name', 'M00002').next()
m2 = g.addV('pathway').property('pathway_name', 'M00527').next()

c1 = g.addV('pathway_component').property('name', 'K00001').next()
c2 = g.addV('pathway_component').property('name', 'K00002').next()
c3 = g.addV('pathway_component').property('name', 'K00003').next()

g.addE('partof').from(c1).to(m1).iterate()
g.addE('partof').from(c2).to(m1).iterate()
g.addE('partof').from(c3).to(m2).iterate()

g1 = g.addV('gene').property('name', 'G00001').next()
g2 = g.addV('gene').property('name', 'G00002').next()
g3 = g.addV('gene').property('name', 'G00003').next()
g4 = g.addV('gene').property('name', 'G00004').next()
g5 = g.addV('gene').property('name', 'G00005').next()
g6 = g.addV('gene').property('name', 'G00006').next()
g7 = g.addV('gene').property('name', 'G00007').next()
g8 = g.addV('gene').property('name', 'G00008').next()

g.addE('isa').from(g1).to(c1).iterate()
g.addE('isa').from(g2).to(c3).iterate()

g.addE('isa').from(g3).to(c1).iterate()
g.addE('isa').from(g4).to(c2).iterate()
g.addE('isa').from(g5).to(c3).iterate()

g.addE('isa').from(g6).to(c1).iterate()
g.addE('isa').from(g7).to(c1).iterate()
g.addE('isa').from(g8).to(c2).iterate()

o1 = g.addV('organism').property('name', 'O000001').next()
o2 = g.addV('organism').property('name', 'O000002').next()
o3 = g.addV('organism').property('name', 'O000003').next()
o4 = g.addV('organism').property('name', 'O000004').next()

g.addE('partof').from(g1).to(o1).iterate()
g.addE('partof').from(g2).to(o1).iterate()
g.addE('partof').from(g3).to(o2).iterate()
g.addE('partof').from(g4).to(o2).iterate()
g.addE('partof').from(g5).to(o3).iterate()
g.addE('partof').from(g6).to(o3).iterate()
g.addE('partof').from(g7).to(o4).iterate()
g.addE('partof').from(g8).to(o4).iterate()

我想计算每个生物体每个通路的基因数,这样结果看起来像这样:

organism_1 pathway_1 gene_count
organism_1 pathway_2 gene_count
organism_2 pathway_1 gene_count
organism_2 pathway_2 gene_count

但是到现在我还没有弄明白。我尝试了以下方法:

g.V().has('pathway', 'pathway_name', within('M00002', 'M00527')).project('organism', 'pathway', 'count'). 
   by(__.in().hasLabel('pathway_component').
       in().hasLabel('gene').
       out().hasLabel('organism').
       values('name')).
   by('pathway_name').
   by(__.in().hasLabel('pathway_component').
       in().hasLabel('gene').
       count())

但看起来分组是错误的:

==>[organism:O000001,pathway:M00002,count:6]
==>[organism:O000001,pathway:M00527,count:2]

在这种情况下,对于所列的两条途径,似乎所有生物体及其计数都被组合在一起(有四种生物体)。我希望看到类似的内容:

O000001 M00002 1
O000001 M00527 1
O000002 M00002 2
O000002 M00527 0
O000003 M00002 1
O000003 M00527 1
O000004 M00002 2
O000004 M00527 0

如何根据不同的生物体和不同的途径拆分结果?

最佳答案

希望下面的最终查询对您有所帮助。我展示了我用来到达那里的步骤,其中一部分是确保我理解你的数据结构。

首先我想看看图形的形状。

gremlin> g.V().hasLabel('pathway').
......1>       in().hasLabel('pathway_component').
......2>       in().hasLabel('gene').
......3>       out().hasLabel('organism').
......4>       path().
......5>         by('pathway_name').
......6>         by('name').
......7>         by('name').
......8>         by('name')
==>[M00002,K00001,G00006,O000003]
==>[M00002,K00001,G00007,O000004]
==>[M00002,K00001,G00001,O000001]
==>[M00002,K00001,G00003,O000002]
==>[M00002,K00002,G00004,O000002]
==>[M00002,K00002,G00008,O000004]
==>[M00527,K00003,G00005,O000003]
==>[M00527,K00003,G00002,O000001] 

然后我使用 pathgroup 来了解更多关于这些关系分组的信息。

gremlin> g.V().hasLabel('pathway').
......1>       in().hasLabel('pathway_component').
......2>       in().hasLabel('gene').
......3>       out().hasLabel('organism').as('org').
......4>       group().
......5>         by(select('org').by('name')).
......6>         by(
......7>       path().
......8>         by('pathway_name').
......9>         by('name').
.....10>         by('name').
.....11>         by('name').fold()).
.....12>       unfold()
==>O000004=[path[M00002, K00001, G00007, O000004], path[M00002, K00002, G00008, O000004]]
==>O000003=[path[M00002, K00001, G00006, O000003], path[M00527, K00003, G00005, O000003]]
==>O000002=[path[M00002, K00001, G00003, O000002], path[M00002, K00002, G00004, O000002]]
==>O000001=[path[M00002, K00001, G00001, O000001], path[M00527, K00003, G00002, O000001]] 

最后我将上面的查询更改为嵌套两个组

gremlin> g.V().hasLabel('pathway').as('pathway').
......1>       in().hasLabel('pathway_component').
......2>       in().hasLabel('gene').as('gene').
......3>       out().hasLabel('organism').as('org').
......4>       group().
......5>         by(select('org').by('name')).
......6>         by(
......7>           group().
......8>             by(select('pathway').by('pathway_name')).
......9>             by(select('gene').by('name').fold())).
.....10>       unfold()
==>O000004={M00002=[G00007, G00008]}
==>O000003={M00002=[G00006], M00527=[G00005]}
==>O000002={M00002=[G00003, G00004]}
==>O000001={M00002=[G00001], M00527=[G00002]}  

这会产生有机体、通路名称和基因。

在此基础上,我再次更改查询以生成计数。我希望这接近您的需要。

gremlin> g.V().hasLabel('pathway').as('pathway').
......1>       in().hasLabel('pathway_component').
......2>       in().hasLabel('gene').as('gene').
......3>       out().hasLabel('organism').as('org').
......4>       group().
......5>         by(select('org').by('name')).
......6>         by(
......7>           group().
......8>             by(select('pathway').by('pathway_name')).
......9>             by(select('gene').by('name').fold().count(local))).
.....10>       unfold()
==>O000004={M00002=2}
==>O000003={M00002=1, M00527=1}
==>O000002={M00002=2}
==>O000001={M00002=1, M00527=1}

关于gremlin - 对来自不同顶点的属性进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60573254/

相关文章:

node.js - 在 AWS 上使用 Titan DynamoDB 并从 NodeJs 进行查询

python - Gremlin 使用灯泡通过 Groovy 脚本进行查询

python - 同一图表上的同一查询在 Neptune 与 Gremlify 上返回不同的结果

Scala、gremlin-scala、HLists、Poly2、RightFold 和缺失的隐式 Prepend

python - gremlinpython - 以字符串形式返回 id 和标签

neo4j - 是否可以在大型密集图上使用 graphdb

azure - 如何使用 Gremlin API 在 Azure Cosmos DB 中创建元图

java - 如何在 Titan Graph 数据库中使用 Java API 在新顶点和现有顶点之间创建边

node.js - 将 Azure CosmosDB DocumentDB API 与 Graph API 结合使用

titan - Gremlin 查询通过跨多个顶点属性的搜索键进行搜索