如何编写Gremlin查询判断指定值是否存在于所有嵌套子列表中
Gremlin实现:判断指定值是否存在于所有返回子列表中
当前使用的基础Gremlin查询如下:
g.V("JobDefinition1"). out("JobDependency"). coalesce(out('JobDefinitionToJobHistory').has("Timestamp", between("2022-06-21T00:00:00Z", "2022-06-25T00:00:00Z")).has("Status", 2).values("Timestamp").fold(), constant("0001-00-00T00:00:00Z"))
该查询返回嵌套字符串列表结构,示例返回值:
[ [ "2022-06-21T00:00:00Z", "2022-06-23T00:00:00Z" ], [ "2022-06-20T00:00:00Z", "2022-06-23T00:00:00Z" ] ]
需求为判断指定值(例如"2022-06-21T00:00:00Z")是否存在于每一个子列表中,以上述示例为例,目标值不在第二个子列表内,最终需要返回布尔值false。
实现语句
直接在原有查询末尾追加判断逻辑即可,替换语句中目标时间字符串为实际需要校验的值:
g.V("JobDefinition1"). out("JobDependency"). coalesce(out('JobDefinitionToJobHistory').has("Timestamp", between("2022-06-21T00:00:00Z", "2022-06-25T00:00:00Z")).has("Status", 2).values("Timestamp").fold(), constant("0001-00-00T00:00:00Z")). // 逐个校验子列表是否包含目标值,返回对应布尔结果 map(unfold().is("2022-06-21T00:00:00Z").fold().count(Scope.local).is(gt(0))). // 收集所有校验结果,判断是否全部为true fold(). match( __.as("checkResults").unfold().is(true).count().as("passCount"), __.as("checkResults").count(Scope.local).as("totalCount"), __.where("passCount", eq("totalCount")) ). hasNext()
如果使用的Gremlin版本支持all断言步,可以替换末尾的match逻辑为更简洁的写法,执行效果一致:
.fold().all(eq(true))
低版本Gremlin不支持all步时,使用上述match写法兼容性更好。
逻辑说明
map步处理每个遍历到的子列表:展开子列表元素匹配目标值,只要存在匹配项就对应当前子列表返回true,无匹配则返回false。- 所有子列表的校验结果收集为列表后,统计通过校验的数量和总子列表数量,两者相等则说明所有子列表都包含目标值,最终返回
true,否则返回false。 - 用给出的示例数据测试时,第一个子列表校验返回
true、第二个返回false,最终结果为false,符合预期。
内容的提问来源于stack exchange,提问作者wei wang
相关产品推荐
相关产品推荐

