cassandra - Tinkerpop Gremlin - 如何将变量聚合到遍历独立集合中

标签 cassandra gremlin tinkerpop datastax-enterprise-graph

我目前正在阅读 The Practitioner's Guide to Graph Data 并试图解决以下问题(仅用于学习目的)。以下是书籍电影数据集的上下文,在此示例中,它使用了一个“标签”顶点、一个“电影”顶点和一个“评级”边,其评级属性值为 1-5 。

只是为了练习,并为了扩展我对书中概念的理解,我想将所有电影都标记为“喜剧”并计算平均 NPS。为此,我想将所有正面 (+1) 和中性或负面 (-1) 评级汇总到一个列表中。然后我希望将这些值的总和除以该列表中的变量数量(平均值)。这就是我的尝试:

dev.withSack{[]}{it.clone()}.    // create a sack with an empty list that clones when split
V().has('Tag', 'tag_name', 'comedy').
    in('topic_tagged').as('film').    // walk to movies tagged as comedy
    inE('rated').    // walk to the rated edges
        choose(values('rating').is(gte(3.0)),
            sack(addAll).by(constant([1.0])),
            sack(addAll).by(constant([-1.0]))).    // add a value or 1 or -1 to this movies list, depending on the rating
    group().
        by(select('film').values('movie_title')).
        by(project('a', 'b').
            by(sack().unfold().sum()).    // add all values from the list
            by(sack().unfold().count()).    // Count the values in the list
            math('a / b')).
    order(local).
        by(values, desc)

最后每部电影要么是“1.0”要么是“-1.0”。

"Journey of August King The (1995)": "1.0",
"Once Upon a Time... When We Were Colored (1995)": "1.0", ...

在我的测试中,这些值似乎没有按照我的预期聚合到集合中。我尝试了各种方法,但都没有达到我的预期结果。

我知道我可以通过在初始值为“0.0”的麻袋中加减,然后除以边数来实现这个结果,但我希望通过使用列表并避免使用更有效的解决方案额外遍历边缘以获得计数。

是否可以使用列表来实现我的结果?如果是,怎么办?

编辑 1:

下面的代码更简单,取自 Kelvins 示例,将通过简单地使用折叠步骤来汇总每个评分:

dev.V().
    has('Tag', 'tag_name', 'comedy').
        in('topic_tagged').
        project('movie', 'result').
            by('movie_title').
            by(inE('rated').
                choose(values('rating').is(gte(3.0)),
                    constant(1.0),
                    constant(-1.0)).
                fold())    // replace fold() with mean() to calculate the mean, or do something with the collection

我有点尴尬,因为折叠和展开太常见了,我完全忘记了折叠步骤。我猜想多了。

最佳答案

您可能会考虑使用 aggregate 而不是 sack 的不同方法。您还可以使用 mean 步骤来避免需要 math 步骤。由于我没有您的数据,因此我做了一个示例,该示例使用航线数据集并使用机场海拔高度而不是您案例中的电影评级。

gremlin> g.V().hasLabel('airport').limit(10).values('elev')
==>1026
==>151
==>542
==>599
==>19
==>143
==>14
==>607
==>64
==>313  

使用与您的 yield 类似的加权系统

gremlin> g.V().hasLabel('airport').limit(10).
......1>   choose(values('elev').is(gt(500)),
......2>     constant(1),
......3>     constant(-1))
==>1
==>-1
==>1
==>1
==>-1
==>-1
==>-1
==>1
==>-1
==>-1    

这些结果可以聚合成一个批量集

gremlin> g.V().hasLabel('airport').limit(10).
......1>   choose(values('elev').is(gt(500)),
......2>     constant(1),
......3>     constant(-1)).
......4>   aggregate('x').
......5>   cap('x')
==>[1,1,1,1,-1,-1,-1,-1,-1,-1]  

从那里我们可以取平均值

gremlin> g.V().hasLabel('airport').limit(10).
......1>   choose(values('elev').is(gt(500)),
......2>     constant(1),
......3>     constant(-1)).
......4>   aggregate('x').
......5>   cap('x').
......6>   unfold().
......7>   mean()
==>-0.2    

现在,这当然是人为设计的,因为您通常不会执行 aggregate('x').cap('x').unfold().mean() 您只会使用 mean() 本身。但是使用这种模式你应该能够解决你的问题。

编辑添加

仔细考虑一下,您甚至可以在不需要 aggregate 的情况下编写查询 - 如下所示。我使用航线距离边缘属性来模拟类似于您的查询的内容。该示例仅使用一个机场以保持简单。首先只是创建分数列表...

gremlin> g.V().has('airport','code','SAF').
......1>   project('airport','mean').
......2>     by('code').
......3>     by(outE().
......4>        choose(values('dist').is(gt(350)),
......5>          constant(1),
......6>          constant(-1)).
......7>          fold())
==>[airport:SAF,mean:[1,1,1,-1]]   

最后创造平均值

gremlin> g.V().has('airport','code','SAF').
......1>   project('airport','mean').
......2>     by('code').
......3>     by(outE().
......4>        choose(values('dist').is(gt(350)),
......5>          constant(1),
......6>          constant(-1)).
......7>          mean())
==>[airport:SAF,mean:0.5]

再次编辑

如果边缘属性可能不存在,你可以这样做......

gremlin> g.V().has('airport','code','SAF').
......1>   project('airport','mean').
......2>     by('code').
......3>     by(outE().
......4>        coalesce(values('x'),constant(100)).
......5>        choose(identity().is(gt(350)),
......6>          constant(1),
......7>          constant(-1)).
......8>          fold())
==>[airport:SAF,mean:[-1,-1,-1,-1]]  

关于cassandra - Tinkerpop Gremlin - 如何将变量聚合到遍历独立集合中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63843563/

相关文章:

ssl - Cassandra.yaml 设置客户端 SSL

cassandra - Cassandra 压力测试

Gremlin:无法使用控制台向图形添加边

groovy - Gremlin 存储 GremlinGroovyPipeline 并对其调用 .count() 时

node.js - 在 gremlin javascript 中使用谓词

python - 如何使用 gremlin python 在 gremlin 服务器上提交更改

java - Gremlin drop() 无法通过 java api 工作

java - 在 Apache Cassandra + Hector + Java 的键空间上插入行

Cassandra 多重获取性能

python - Gremlin 绑定(bind)方法支持