【问题标题】:How to filter related objects using Gremlin Cosmos DB?如何使用 Gremlin Cosmos DB 过滤相关对象?
【发布时间】:2020-12-03 12:11:58
【问题描述】:

我想获得一个包含一个用户的对象的 ResultSet 和一个尚未与该用户相关的所有用户的列表。 结果应如下所示:

[[user: [USEROBJECT], usersThatAreNotFriends: [[USEROBJECT]...]]...]

我正在使用 Cosmos DB Gremlin Endpoint,并且难以过滤/组合已经相关的用户和所有用户。

我的想法是:

g.V().hasLabel('user').as('user').flatMap(g.V().hasLabel('user').where(__.eq(select('user').out('isFriend')).fold()).as('usersThatAreNotFriends').select('user', 'usersThatAreNotFriends')

要设置我的示例,请使用:

g.addV('user').property('id','user_1').property('partition_key','1')
g.addV('user').property('id','user_2').property('partition_key','2')
g.addV('user').property('id','user_3').property('partition_key','3')
g.addV('user').property('id','user_4').property('partition_key','4')
g.V('user_1').addE('has_relation').to(g.V('user_2'))
g.V('user_2').addE('has_relation').to(g.V('user_1'))
g.V('user_2').addE('has_relation').to(g.V('user_4'))
g.V('user_4').addE('has_relation').to(g.V('user_2'))

预期的结果应该以简单的方式表示:

[user_1: [user_3, user_4], user_2:[user_3], 
user_3:[user_1, user_2, user_3], user_4:[user_1, user_3]]

【问题讨论】:

  • 如果您可以添加一小组addV 和addE 步骤来构建代表您的数据的示例图,将会很有帮助。

标签: .net gremlin azure-cosmosdb-gremlinapi gremlinnet


【解决方案1】:

我修改了您的查询以将 ID 添加为真实 ID

g.addV('user').property(id,'user_1').property('partition_key','1')
g.addV('user').property(id,'user_2').property('partition_key','2')
g.addV('user').property(id,'user_3').property('partition_key','3')
g.addV('user').property(id,'user_4').property('partition_key','4')
g.V('user_1').addE('has_relation').to(g.V('user_2'))
g.V('user_2').addE('has_relation').to(g.V('user_1'))
g.V('user_2').addE('has_relation').to(g.V('user_4'))
g.V('user_4').addE('has_relation').to(g.V('user_2'))   

在您的示例中,有时您会在结果中显示同一个人,因此我建议使用两个不同的查询。第一个包括该人不与自己成为朋友。

gremlin> g.V().as('p').
......1>    project('person','not-friends').
......2>      by().
......3>      by(V().where(__.not(__.in('has_relation').as('p'))).fold())
==>[person:v[user_3],not-friends:[v[user_3],v[user_2],v[user_1],v[user_4]]]
==>[person:v[user_2],not-friends:[v[user_3],v[user_2]]]
==>[person:v[user_1],not-friends:[v[user_3],v[user_1],v[user_4]]]
==>[person:v[user_4],not-friends:[v[user_3],v[user_1],v[user_4]]] 

如果您想避免此人在结果中显示为不是自己的朋友,您可以这样做:

gremlin>  g.V().as('p').
......1>    project('person','not-friends').
......2>      by().
......3>     by(V().where(__.not(__.in('has_relation').as('p')).where(neq('p'))).fold())
==>[person:v[user_3],not-friends:[v[user_2],v[user_1],v[user_4]]]
==>[person:v[user_2],not-friends:[v[user_3]]]
==>[person:v[user_1],not-friends:[v[user_3],v[user_4]]]
==>[person:v[user_4],not-friends:[v[user_3],v[user_1]]]

作为旁注,您可以使用简单的group().by() 方法来查找谁是朋友。

gremlin> g.V().aggregate('all').group().by().by(out().fold()).unfold()
==>v[user_3]=[]
==>v[user_2]=[v[user_1], v[user_4]]
==>v[user_1]=[v[user_2]]
==>v[user_4]=[v[user_2]]    

【讨论】:

  • 问题在于,您不能在 Azure Cosmos DB 中使用简单的符号 V:ExceptionType:GraphCompileException ExceptionMessage:Gremlin 查询编译错误:无法在当前上下文中解析符号“V”。 @ 第 1 行,第 56 列。1 错误来源:Microsoft.Azure.Cosmos.Gremlin.Core GremlinRequestId:a69f7871-2ae5-4645-91f0-0cb7af165601 上下文:graphcompute 范围:graphparse-translate-validatesymbolresolution GraphInterOpStatusCode:QuerySyntaxError HResult:0x8013150输入 ':help' 或 ':h' 寻求帮助。
  • 好的,使用中间遍历V() 是相当普遍的,所以它似乎是解决这个问题的自然方法。我添加了一种方法来询问仅使用组的逆问题。也许使用它并在您的应用程序中完成其余的工作。如果时间允许,我会尝试添加另一种形式。
  • 非常感谢您的快速答复。希望 Cosmos DB 很快能够更好地支持整个 Gremlin API...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多