within() 子句中的 Gremlin 查询遍历

Gremlin query traversal in within() clause

我有如下所示的最小 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 类型,由 class/functionalClass 顶点的入站边定义。

我有以下查询就在那里 - 获取 measurements

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')

问题在于,这只会 return 与泵直接相关的 class 相关的测量(示例图中的 measurement1) ,而我想获得与 parents 和 grandparents 相关的测量值 class 泵与 (measurement1 AND measurement2 在示例图中)。

我知道我可以通过查询

获得class1的parents
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

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

的操作
where(eq('a')).by(id)

where(within('a'))

其中 'a' 是第一种情况下的顶点集合或第二种情况下的顶点或 id 值的集合。