【问题标题】:Gremlin query traversal in within() clausewithin() 子句中的 Gremlin 查询遍历
【发布时间】:2020-09-19 12:56:22
【问题描述】:

我有如下所示的最小 Gremlin 图

Sample graph

可以使用以下 Gremlin 构建此图:-

g.addV('type').property(id, 'discipline').addV('type').property(id, 'functionalClass').addV('type').property(id, 'class1').addV('type').property(id, 'class2').addV('equipment').property(id, 'pump').addV('deployment').property(id, 'deployment1').addV('measure').property(id, 'measurement1').addV('measure').property(id, 'measurement2')
g.V('discipline').addE('hasChild').to(g.V('functionalClass'))
g.V('functionalClass').addE('hasChild').to(g.V('class1'))
g.V('functionalClass').addE('hasChild').to(g.V('class2'))
g.V('pump').addE('hasClass').to(g.V('class1'))
g.V('pump').addE('hasDeployment').to(g.V('deployment1'))
g.V('functionalClass').addE('measurement').to(g.V('measurement2'))
g.V('functionalClass').addE('summaryMeasurement').to(g.V('measurement2'))
g.V('class1').addE('measurement').to(g.V('measurement1'))
g.V('class2').addE('measurement').to(g.V('measurement1'))
g.V('deployment1').addE('produces').to(g.V('measurement1'))
g.V('deployment1').addE('produces').to(g.V('measurement2'))

我正在使用的查询应该获取给定泵的部署和相关测量。测量可以是 measurementsummaryMeasurement 类型,由类/功能类顶点的入站边定义。

我有以下查询就在那里 - 获取测量结果

g.V('pump').as('e').out('hasClass').as('c')
 .select('e').out('hasDeployment').as('d')
 .out('produces').as('m')
 .in('measurement').where(eq('c'))
 .select('d', 'm')

以及以下获得summaryMeasurements

g.V('pump').as('e').out('hasClass').as('c')
 .select('e').out('hasDeployment').as('d')
 .out('produces').as('m')
 .in('summary_measurement').where(eq('c'))
 .select('d', 'm')

问题在于,这只会返回与泵直接相关的类相关的测量值(示例图中的 measurement1),而我想获得与父母和泵相关类的祖父母(measurement1 AND measurement2 在示例图中)。

我知道我可以通过查询获得 class1 的父母

g.V('class1').union(__.id(), repeat(__.in('hasChild')).emit().id())

我尝试了以下查询失败

g.V('pump').as('e').out('hasClass').as('c')
.select('e').out('hasDeployment').as('d')
.out('produces').as('m')
.in('measurement')
.where(hasId(within(select('c').union(__.id(), repeat(__.in('hasChild')).emit().id()))))
.select('d', 'm')

我收到以下错误(这是在 Neptune 上)

Expected an id that is convertible to String but received class com.amazon.neptune.tinkerpop.structure.NeptuneGraph$NeptuneGraphTraversal

【问题讨论】:

    标签: gremlin tinkerpop3 amazon-neptune


    【解决方案1】:

    因此,hasId 只能接受一个或多个 ID 值的列表,而 within 是一个谓词 (P),只能接受一个值列表或一个值集合,而不是遍历。您将需要稍微重组您的查询以首先构建一个集合,可能使用aggregate,然后执行类似的操作

    where(eq('a')).by(id)
    

    where(within('a'))
    

    “a”在第一种情况下是顶点集合,在第二种情况下是顶点或 id 值的集合。

    【讨论】:

    • 感谢您快速而有帮助的回答 Kelvin。我能够使用它来创建以下查询,该查询给了我预期的结果g.V('pump').as('e').out('hasClass').union(unfold(), repeat(__.in('hasChild')).emit()).aggregate('agg').unfold().as('c').select('e').out('hasDeployment').as('d').out('produces').as('m').in('summaryMeasurement').where(eq('c')).select('m', 'd')