格莱姆林: 如何解决属性为空的问题,并编写一个查询以更新某个顶点的所有属性?

4
我需要编写一个单独的 Gremlin 查询,可以设置顶点的新属性值。所有属性名称都事先已知(在此示例中为:Type、Country、Status)。一些属性值可能为空 - 我事先不知道哪些为空。查询应适用于所有情况。例如,假设我当前有以下查询:
g.V(123).
property('Type',Type).
property('Country',Country).
property('Status',Status)

如果所有参数(类型、国家、状态)的值都不为空,则此查询正常工作。但是,如果例如国家为空,我会收到以下错误:

The AddPropertyStep does not have a provided value: AddPropertyStep({key=[Country]})

在这种情况下,我需要使用另一个查询来删除该属性(顺便问一下,有没有更好的方法来删除属性?):

g.V(123).
property('Type',Type).
property('Status',Status).
properties('Country').drop()

是否可能编写一个通用查询,以处理空值和非空值?我不能使用控制台或编程,只能执行单个Gremlin查询。

谢谢!

1个回答

3

TinkerPop 不允许属性中存在 null 值(虽然我想你可能会在某些图形数据库中发现不同的语义),因此您应该提前验证数据,以确保它具有一些有意义的“空值”,而不是 null。如果由于某种原因无法完成此操作,那么您可以使用 choose() 步骤来“检查 null”:

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().has('person','name','marko').valueMap()
==>[name:[marko],age:[29]]
gremlin> age = null
gremlin> g.V().has('person','name','marko').choose(constant(age).count().is(0), properties('age').drop(),property('age',age))
gremlin> g.V().has('person','name','marko').valueMap()
==>[name:[marko]]
gremlin> age = 30
==>30
gremlin> g.V().has('person','name','marko').choose(constant(age).count().is(0), properties('age').drop(),property('age',age))
==>v[1]
gremlin> g.V().has('person','name','marko').valueMap()
==>[name:[marko],age:[30]]

"isNull"检查基本上只是:constant(age).count().is(0),它依赖于Gremlin对流中null值的语义,即为空并且count()为零。虽然它可行,但会使你的Gremlin代码更难以阅读。如果你经常需要编写这个检查,那么将其作为DSL步骤添加可能是一个不错的选择。参考文档"

太好了,非常感谢!查询应该看起来像这样。它似乎工作得很好。它可以简化吗?g.V(123).choose(constant(Type).count().is(0), optional(properties('Type').drop()), property('Type',Type)).choose(constant(Status).count().is(0)...... - Arturs
我不确定你在例子中所说的“简化”是什么意思,但你可能是对的,使用optional()可以在末尾链接更多步骤,因为drop()行为类似于过滤器步骤并杀死所有遍历者。不过,使用sideEffect()而不是optional()可能更易读...至少这是我的偏好。 - stephen mallette

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接