首页 > 解决方案 > 关于可能不存在的属性值的数学

问题描述

这是一个查询(gremlin-python;tinkerpop v3.3.3),它插入一个具有“正”和“负”属性的节点,然后从另一个中减去一个并输出结果:

g.withSack(0).addV('test').property('positive', 2).property('negative', 3) \
                            .sack(assign).by('positive') \
                            .sack(minus).by('negative') \
                            .sack().next()
Out[13]: -1

尝试相同的查询,但缺少其中一个属性会产生错误:

g.withSack(0).addV('test').property('positive', 2) \
                            .sack(assign).by('positive') \
                            .sack(minus).by('negative') \
                            .sack().next()
Out[13]: ... GremlinServerError: 500: The property does not exist as the key has no associated value for the provided element: v[36]:negative

我可以通过合并四种可能的情况来解决这个问题:

g.withSack(0).addV('test').property('positive', 2) \
    .coalesce(has('positive').has('negative').sack(assign).by('positive').sack(minus).by('negative').sack(), \
                has('positive').values('positive'), \
                has('negative').sack(minus).by('negative').sack(), \
                sack() \
                ).next()

虽然它确实很丑 - 有没有更整洁的解决方案?理想情况下,可以在没有属性的情况下插入默认值。我也尝试过使用“数学”步骤,但它只是稍微整洁一些,并且不能避免不存在属性的问题。需要明确的是,在多个遍历器的情况下,我想要每个遍历器的结果。

标签: gremlin

解决方案


我认为如果你这样做math()sack()解决这个问题,你可能应该考虑在你打算进行这些计算的这些顶点上具有“必需”属性的想法。这应该会让事情变得容易得多。我确实觉得math()会更整洁,尽管您另有说法:

g.V().as('a').out('knows').as('b').
  math("a - b").
    by(coalesce(values('hasSomeValue'), constant(0))).
    by(coalesce(values('missingValue'), constant(0)))

这很简单,尽管您的示例可能是为了简单,而您需要考虑更多的复杂性。

by()我想如果第一次遍历没有返回任何东西,我想 Gremlin 可以更改为允许第二个参数作为默认值,因此:

g.V().as('a').out('knows').as('b').
  math("a - b").
    by(values('hasSomeValue'), constant(0)).
    by(values('missingValue'), constant(0))

节省了一些我想的打字,但我不确定它是否像使用coalesce(). 我想我喜欢coalesce()更好的显式使用。


推荐阅读