查找与其他人购买相同游戏的人
Find people who bought the same games as someone else
我正在使用 Amazon Neptune 创建和查询一个简单的图形数据库。我目前 运行 我的代码在 AWS Jupyter Notebook 中,但最终会将代码移动到 Python (gremlin_python)。正如您可能猜到的那样,我对 Gremlin 和一般图形数据库还很陌生。
我有以下数据
g.addV('person').property(id, 'john')
.addV('person').property(id, 'jim')
.addV('person').property(id, 'pam')
.addV('game').property(id, 'G1')
.addV('game').property(id, 'G2')
.addV('game').property(id, 'G3').iterate()
g.V('john').as('p').V('G1').addE('bought').from('p').iterate()
g.V('john').as('p').V('G2').addE('bought').from('p').iterate()
g.V('john').as('p').V('G3').addE('bought').from('p').iterate()
g.V('jim').as('p').V('G1').addE('bought').from('p').iterate()
g.V('jim').as('p').V('G2').addE('bought').from('p').iterate()
g.V('pam').as('p').V('G1').addE('bought').from('p').iterate()
数据库中有 3 个人和 3 个游戏。我的目标是,给定一个人,告诉我哪些人购买了与他们相同的游戏以及那些是哪些游戏
查看示例代码(主要来自 https://tinkerpop.apache.org/docs/current/recipes/#recommendation)后,我有以下代码尝试查找
购买的游戏
g.V('john').as('target') Target person we are interested in comparing against
.out('bought').aggregate('target_games') // Games bought by target
.in('bought').where(P.neq('target')).dedup() // Persons who bought same games as target (excluding target and without duplicates)
.group().by().by(out("bought").where(P.within("target_games")).count()) // Find persons, group by number of co owned games
.unfold().order().by(values, desc).toList() // Unfold to create list, order by greatest number of common games
这给了我结果:
- {v[吉姆]: 2}
- {v[pam]: 1}
这告诉我 jim 有 2 个与 john 相同的游戏,而 pam 只有 1 个。但我希望我的查询 return 他们有共同的实际游戏,就像这样(仍然按最常见游戏):
- {v[吉姆]: ['G1', 'G2']}
- {v[pam]: ['G1]}
感谢您的帮助。
可以用几种不同的方式编写此查询。这是一种使用中间遍历 V
步骤找到 John 的游戏来找到所有其他不是 John 的人,查看他们的游戏并查看它们是否与 John 拥有的游戏相交的方法。
gremlin> g.V('john').as('j').
......1> out().
......2> aggregate('owns').
......3> V().
......4> hasLabel('person').
......5> where(neq('j')).
......6> group().
......7> by(id).
......8> by(out('bought').where(within('owns')).dedup().fold())
==>[pam:[v[G1]],jim:[v[G1],v[G2]]]
但是,中间遍历 V
方法并不是真正需要的,因为您可以只查看来自 Jown 拥有的游戏的传入顶点
gremlin> g.V('john').as('j').
......1> out().
......2> aggregate('owns').
......3> in('bought').
......4> where(neq('j')).
......5> group().
......6> by(id).
......7> by(out('bought').where(within('owns')).dedup().fold())
==>[pam:[v[G1]],jim:[v[G1],v[G2]]]
最后,这是第三种方法,其中 dedup
步骤应用得更快。这可能是三者中效率最高的。
gremlin> g.V('john').as('j').
......1> out().
......2> aggregate('owns').
......3> in('bought').
......4> where(neq('j')).
......5> dedup().
......6> group().
......7> by(id).
......8> by(out('bought').where(within('owns')).fold())
==>[pam:[v[G1]],jim:[v[G1],v[G2]]]
根据评论讨论更新。我不确定这是一个更简单的查询,但您可以从这样的投影中提取 group
:
gremlin> g.V('john').as('j').
......1> out().as('johnGames').
......2> in('bought').
......3> where(neq('j')).as('personPurchasedJohnGames').
......4> project('johnGames','personPurchasedJohnGames').
......5> by(select('johnGames')).
......6> by(select('personPurchasedJohnGames')).
......7> group().
......8> by(select('personPurchasedJohnGames')).
......9> by(select('johnGames').fold())
==>[v[pam]:[v[G1]],v[jim]:[v[G1],v[G2]]]
但实际上你可以进一步减少到
gremlin> g.V('john').as('j').
......1> out().as('johnGames').
......2> in('bought').
......3> where(neq('j')).as('personPurchasedJohnGames').
......4> group().
......5> by(select('personPurchasedJohnGames')).
......6> by(select('johnGames').fold())
==>[v[pam]:[v[G1]],v[jim]:[v[G1],v[G2]]]
所以现在我们有很多选择可供选择!测量这些并查看是否比其他速度更快将很有趣。一般来说,我倾向于避免使用 as
步骤,因为这会导致路径跟踪被打开(耗尽内存),但因为我们已经在其他查询中有一个 as('j')
并不是什么大问题.
再次编辑以添加结果排序
g.V('john').as('j').
out().as('johnGames').
in('bought').
where(neq('j')).as('personPurchasedJohnGames').
group().
by(select('personPurchasedJohnGames')).
by(select('johnGames').fold()).
unfold().
order().
by(select(values).count(local),desc)
{v[jim]: [v[G1], v[G2]]}
{v[pam]: [v[G1]]}
我正在使用 Amazon Neptune 创建和查询一个简单的图形数据库。我目前 运行 我的代码在 AWS Jupyter Notebook 中,但最终会将代码移动到 Python (gremlin_python)。正如您可能猜到的那样,我对 Gremlin 和一般图形数据库还很陌生。
我有以下数据
g.addV('person').property(id, 'john')
.addV('person').property(id, 'jim')
.addV('person').property(id, 'pam')
.addV('game').property(id, 'G1')
.addV('game').property(id, 'G2')
.addV('game').property(id, 'G3').iterate()
g.V('john').as('p').V('G1').addE('bought').from('p').iterate()
g.V('john').as('p').V('G2').addE('bought').from('p').iterate()
g.V('john').as('p').V('G3').addE('bought').from('p').iterate()
g.V('jim').as('p').V('G1').addE('bought').from('p').iterate()
g.V('jim').as('p').V('G2').addE('bought').from('p').iterate()
g.V('pam').as('p').V('G1').addE('bought').from('p').iterate()
数据库中有 3 个人和 3 个游戏。我的目标是,给定一个人,告诉我哪些人购买了与他们相同的游戏以及那些是哪些游戏
查看示例代码(主要来自 https://tinkerpop.apache.org/docs/current/recipes/#recommendation)后,我有以下代码尝试查找
购买的游戏g.V('john').as('target') Target person we are interested in comparing against
.out('bought').aggregate('target_games') // Games bought by target
.in('bought').where(P.neq('target')).dedup() // Persons who bought same games as target (excluding target and without duplicates)
.group().by().by(out("bought").where(P.within("target_games")).count()) // Find persons, group by number of co owned games
.unfold().order().by(values, desc).toList() // Unfold to create list, order by greatest number of common games
这给了我结果:
- {v[吉姆]: 2}
- {v[pam]: 1}
这告诉我 jim 有 2 个与 john 相同的游戏,而 pam 只有 1 个。但我希望我的查询 return 他们有共同的实际游戏,就像这样(仍然按最常见游戏):
- {v[吉姆]: ['G1', 'G2']}
- {v[pam]: ['G1]}
感谢您的帮助。
可以用几种不同的方式编写此查询。这是一种使用中间遍历 V
步骤找到 John 的游戏来找到所有其他不是 John 的人,查看他们的游戏并查看它们是否与 John 拥有的游戏相交的方法。
gremlin> g.V('john').as('j').
......1> out().
......2> aggregate('owns').
......3> V().
......4> hasLabel('person').
......5> where(neq('j')).
......6> group().
......7> by(id).
......8> by(out('bought').where(within('owns')).dedup().fold())
==>[pam:[v[G1]],jim:[v[G1],v[G2]]]
但是,中间遍历 V
方法并不是真正需要的,因为您可以只查看来自 Jown 拥有的游戏的传入顶点
gremlin> g.V('john').as('j').
......1> out().
......2> aggregate('owns').
......3> in('bought').
......4> where(neq('j')).
......5> group().
......6> by(id).
......7> by(out('bought').where(within('owns')).dedup().fold())
==>[pam:[v[G1]],jim:[v[G1],v[G2]]]
最后,这是第三种方法,其中 dedup
步骤应用得更快。这可能是三者中效率最高的。
gremlin> g.V('john').as('j').
......1> out().
......2> aggregate('owns').
......3> in('bought').
......4> where(neq('j')).
......5> dedup().
......6> group().
......7> by(id).
......8> by(out('bought').where(within('owns')).fold())
==>[pam:[v[G1]],jim:[v[G1],v[G2]]]
根据评论讨论更新。我不确定这是一个更简单的查询,但您可以从这样的投影中提取 group
:
gremlin> g.V('john').as('j').
......1> out().as('johnGames').
......2> in('bought').
......3> where(neq('j')).as('personPurchasedJohnGames').
......4> project('johnGames','personPurchasedJohnGames').
......5> by(select('johnGames')).
......6> by(select('personPurchasedJohnGames')).
......7> group().
......8> by(select('personPurchasedJohnGames')).
......9> by(select('johnGames').fold())
==>[v[pam]:[v[G1]],v[jim]:[v[G1],v[G2]]]
但实际上你可以进一步减少到
gremlin> g.V('john').as('j').
......1> out().as('johnGames').
......2> in('bought').
......3> where(neq('j')).as('personPurchasedJohnGames').
......4> group().
......5> by(select('personPurchasedJohnGames')).
......6> by(select('johnGames').fold())
==>[v[pam]:[v[G1]],v[jim]:[v[G1],v[G2]]]
所以现在我们有很多选择可供选择!测量这些并查看是否比其他速度更快将很有趣。一般来说,我倾向于避免使用 as
步骤,因为这会导致路径跟踪被打开(耗尽内存),但因为我们已经在其他查询中有一个 as('j')
并不是什么大问题.
再次编辑以添加结果排序
g.V('john').as('j').
out().as('johnGames').
in('bought').
where(neq('j')).as('personPurchasedJohnGames').
group().
by(select('personPurchasedJohnGames')).
by(select('johnGames').fold()).
unfold().
order().
by(select(values).count(local),desc)
{v[jim]: [v[G1], v[G2]]}
{v[pam]: [v[G1]]}