【问题标题】:CosmosDB gremlin graph: group vertexes and edges by a vertexCosmosDB gremlin 图:按顶点对顶点和边进行分组
【发布时间】:2021-09-14 14:42:44
【问题描述】:

上下文

我正在处理一个非常复杂的图表,但为了更容易理解和给出答案,我创建了以下图表的抽象/简化:

A1 -owns-> B1 -approves-> C1
              -approves-> C2
              -approves-> C3

   -owns-> B2 -approves-> C1

   -owns-> B3 -approves-> C1
              -approves-> C3

A2 -owns-> B4 -approves-> C1
              -approves-> C2
              -approves-> C3

   -owns-> B5 -approves-> C1
              -approves-> C2

   -owns-> B6 -approves-> C1
              -approves-> C3

重要提示:您必须假设 A、B 和 C(以及“批准”边缘具有属性)。感谢@Kelvin Lawrence,我重新创建了图表:

g.addV('A1').property('name','A1Name').property('code','A1Code').as('a1').
  addV('A2').property('name','A2Name').property('code','A2Code').as('a2').
  addV('B1').property('name','B1Name').property('code','B1Code').as('b1').
  addV('B2').property('name','B2Name').property('code','B2Code').as('b2').
  addV('B3').property('name','B3Name').property('code','B3Code').as('b3').
  addV('B4').property('name','B4Name').property('code','B4Code').as('b4').
  addV('B5').property('name','B5Name').property('code','B5Code').as('b5').
  addV('B6').property('name','B6Name').property('code','B6Code').as('b6').
  addV('C1').property('name','C1Name').property('code','C1Code').as('c1').
  addV('C2').property('name','C2Name').property('code','C2Code').as('c2').
  addV('C3').property('name','C3Name').property('code','C3Code').as('c3').
  addE('owns').from('a1').to('b1').
  addE('owns').from('a1').to('b2').
  addE('owns').from('a1').to('b3').
  addE('owns').from('a2').to('b4').
  addE('owns').from('a2').to('b5').
  addE('owns').from('a2').to('b6').
  addE('approves').property('type','00').from('b1').to('c1').
  addE('approves').property('type','01').from('b1').to('c2').
  addE('approves').property('type','02').from('b1').to('c3').
  addE('approves').property('type','03').from('b2').to('c1').
  addE('approves').property('type','04').from('b3').to('c1').
  addE('approves').property('type','00').from('b3').to('c3').
  addE('approves').property('type','01').from('b4').to('c1').
  addE('approves').property('type','02').from('b4').to('c2').
  addE('approves').property('type','03').from('b4').to('c3').
  addE('approves').property('type','04').from('b5').to('c1').
  addE('approves').property('type','00').from('b5').to('c2').
  addE('approves').property('type','01').from('b6').to('c1').
  addE('approves').property('type','02').from('b6').to('c3')

问题/我需要什么

以A1的id作为输入,我想检索数据如下(解释如下):

[
 C1
 {
  properties,
  [
  {
   B1 { properties },
   approvedbyB1 { properties }
  },
  {
   B2 { properties },
   approvedbyB2 { properties }
  },
  {
   B3 { properties },
   approvedbyB3 { properties }
  }
  ]
 },
 C2
 {
  properties,
  [
  {
   B1 { properties },
   approvedbyB1 { properties }
  },
  {
   B2 { properties }
  },
  {
   B3 { properties },
  }
  ]
 },
 C3
 {
  properties,
  [
  {
   B1 { properties },
   approvedbyB1 { properties }
  },
  {
   B2 { properties }
  },
  {
   B3 { properties },
   approvedbyB3 { properties }
  }
  ]
 }
]

本质上,它是一个“C”列表(及其所有属性),其中包含一个由给定“A”拥有的“B”列表(及其所有属性及其各自的批准,如果存在)。

使用“A1”作为输入,理想情况下,结果如下所示:

[
  C1:[B1{B1approval}, B2{B2approval}, B3{B3approval}],
  C2:[B1{B1approval}, B2, B3],
  C3:[B1{B1approval}, B2, B3{B3approval}
]

但是这样的事情也是可以接受的:

[
  C1:[B1{B1approval}, B2{B2approval}, B3{B3approval}],
  C2:[B1{B1approval}],
  C3:[B1{B1approval}, B3{B3approval}
]

注意:检索整个对象及其所有属性对我来说很重要,而不仅仅是 id。


结论/我已经尝试过了

我正在为 Gremlin 图使用 CosmosDB 实现,我尝试过使用 union、select、where 和 groupby 步骤,但我没有设法以这种方式检索数据。

正如我之前所说,如果 JSON 在未经批准的情况下不包含“Bs”也是可以接受的,但理想情况下我需要该信息。

如果您需要更多信息来了解或以特定方式解决问题,请告诉我。

提前致谢!

【问题讨论】:

    标签: azure graph azure-cosmosdb gremlin azure-cosmosdb-gremlinapi


    【解决方案1】:

    首先,我创建了以下步骤来创建您描述的图表。

    g.addV('A1').as('a1').
      addV('A2').as('a2').
      addV('B1').as('b1').
      addV('B2').as('b2').
      addV('B3').as('b3').
      addV('B4').as('b4').
      addV('B5').as('b5').
      addV('B6').as('b6').
      addV('C1').as('c1').
      addV('C2').as('c2').
      addV('C3').as('c3').
      addE('owns').from('a1').to('b1').
      addE('owns').from('a1').to('b2').
      addE('owns').from('a1').to('b3').
      addE('owns').from('a2').to('b4').
      addE('owns').from('a2').to('b5').
      addE('owns').from('a2').to('b6').
      addE('approves').from('b1').to('c1').
      addE('approves').from('b1').to('c2').
      addE('approves').from('b1').to('c3').
      addE('approves').from('b2').to('c1').
      addE('approves').from('b3').to('c1').
      addE('approves').from('b3').to('c3').
      addE('approves').from('b4').to('c1').
      addE('approves').from('b4').to('c2').
      addE('approves').from('b4').to('c3').
      addE('approves').from('b5').to('c1').
      addE('approves').from('b5').to('c2').
      addE('approves').from('b6').to('c1').
      addE('approves').from('b6').to('c3')      
    

    接下来我们可以沿着A1的路径找到对应的C1,C2,C3

    gremlin> g.V().hasLabel('A1').out('owns').out('approves').dedup().label()
    ==>C1
    ==>C2
    ==>C3 
    

    完成后,我们可以找到 Bs

    gremlin>  g.V().hasLabel('A1').as('a1').
    ......1>        out('owns').
    ......2>        out('approves').
    ......3>        dedup().
    ......4>        group().
    ......5>          by(label).
    ......6>          by(__.in('approves').where(__.in('owns').as('a1')).label().fold())
    
    ==>[C3:[B1,B3],C1:[B1,B2,B3],C2:[B1]]   
    

    借助这些构建块,您应该能够生成所需的准确查询。由于您的示例架构中没有属性,因此我无法显示这些属性。

    【讨论】:

    • 非常感谢凯文!它有帮助,但这不是我所需要的,因为我还需要检索 Cs 的属性,据我所知,组步骤仅允许您创建一个键:值列表,其中键只能是单个值.如果我错了,请原谅我 P.S:我在帖子中添加了更多细节和你的图表,再次感谢!
    • 键和或值可以是另一个映射。您还可以嵌套group 步骤。
    • 有cosmosDB的实现吗?出于某种原因,有一些特定的方法可以使用在 CosmosDB 中不起作用的步骤/语法。您能提供样品或样品链接吗?谢谢!
    • 我不知道我害怕。 Gremlin/TinkerPop 允许这样做 - 不确定 CosmosDB 的具体实施限制。
    • 再次感谢凯文。我正在寻找实现它的方法,如果在我解决它之前没有发布解决方案,我将自己发布解决方案。无论如何,谢谢你的领导!
    猜你喜欢
    • 2020-03-18
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    相关资源
    最近更新 更多