如何为通过 CSV 导入 AWS Neptune 的 Vertex 属性安排单一基数?
How do i arrange Single cardinality for Vertex properties imported via CSV into AWS Neptune?
Neptune 文档说他们仅在通过 CSV 导入的 属性 数据上支持 "Set" 属性 基数,这意味着新到达的 属性 值不可能在同一个 属性 上覆盖同一个顶点上的旧 属性 值。
例如,如果第一个 CSV 导入
~id,~label,age
Marko,person,29
然后 Marko 过生日 & 第二个 CSV 导入
~id,~label,age
Marko,person,30
'Marko' 顶点 'age' 属性 将包含两个年龄值,这似乎没有用。
AWS 说这个(折叠设置为单一基数属性(仅保留最后到达的值)需要通过 Gremlin 遍历 post-处理来完成。
这是否意味着应该有一个遍历,连续扫描具有多个(Set)属性的 Vertexes 并再次设置 属性 为 Single cardinality,最后一个可能的值?如果是这样,执行此操作的最佳 Gremlin 查询是什么?
在 pseudo-Gremlin 中,我会想象这样的事情:
g.V().property(single, properties(*), _.tail())
是否可以保证 Set-cardinality 属性始终按到达顺序列出?
还是我完全走错了路。
如有任何帮助,我们将不胜感激。
更新:
所以到目前为止,我能想到的最好的事情仍然远非完美的解决方案,但它仍然可能对我这样的人有用。
在计划 A 中,如果我们碰巧知道 属性 名称并且到达的顺序根本不重要(只需要这些道具上的单一基数),则所有顶点的遍历可能类似于:
g.V().has(${propname}).where(property(single, ${propname}, properties(${propname}).value().order().tail() ) )
计划B是在同一顶点(例如以_开头)的临时属性名称下收集新的属性值,并遍历具有此类临时属性的顶点命名并使用单基数的尾部值设置原始属性:
g.V().has(${temp_propname}).where(property(single, ${propname}, properties(${temp_propname}).value().order().tail() ) ).properties('temp_propname').drop()
计划 C,这将是最酷的,但不幸的是不起作用,它是在专用顶点中继续收集 属性 值,使用纪元时间戳作为 属性 名称,并且 属性 值作为它们的值:
g.V(${vertexid}).out('has_propnames').properties()
==>vp[1542827843->value1]
==>vp[1542827798->value2]
==>vp[1542887080->latestvalue]
并对 属性 名称(键)进行排序,取最后一个,并使用其值使主顶点 属性 值与最新值保持同步:
g.V().has(${propname}).where(out(${has_these_properties}).count().is(gt(0))).where(property(single, ${propname}, out(${has_these_properties}).properties().value( out(${has_these_properties}).properties().keys().order().tail() ) ) )
看起来 value() 步骤的参数必须是常量,它不能使用另一个遍历的结果作为参数,所以我无法让它工作。也许有更多 Gremlin 经验的人知道解决方法。
读取要从中批量加载的文件并使用顶点 ID 设置 属性 可能会更高效,而不是扫描具有多个值的顶点 属性.
因此您的 gremlin 更新查询如下。
g.V(${id})
.property(single,${key},${value})
至于set是不是保证顺序,我不知道。 :(
AWS 最近在 CSV 批量加载器上引入了 'single' 基数支持:
https://docs.aws.amazon.com/neptune/latest/userguide/bulk-load-tutorial-format-gremlin.html
因此,不再需要 Gremlin 级别的 属性 价值安排。
Neptune 文档说他们仅在通过 CSV 导入的 属性 数据上支持 "Set" 属性 基数,这意味着新到达的 属性 值不可能在同一个 属性 上覆盖同一个顶点上的旧 属性 值。
例如,如果第一个 CSV 导入
~id,~label,age
Marko,person,29
然后 Marko 过生日 & 第二个 CSV 导入
~id,~label,age
Marko,person,30
'Marko' 顶点 'age' 属性 将包含两个年龄值,这似乎没有用。
AWS 说这个(折叠设置为单一基数属性(仅保留最后到达的值)需要通过 Gremlin 遍历 post-处理来完成。
这是否意味着应该有一个遍历,连续扫描具有多个(Set)属性的 Vertexes 并再次设置 属性 为 Single cardinality,最后一个可能的值?如果是这样,执行此操作的最佳 Gremlin 查询是什么?
在 pseudo-Gremlin 中,我会想象这样的事情:
g.V().property(single, properties(*), _.tail())
是否可以保证 Set-cardinality 属性始终按到达顺序列出?
还是我完全走错了路。
如有任何帮助,我们将不胜感激。
更新: 所以到目前为止,我能想到的最好的事情仍然远非完美的解决方案,但它仍然可能对我这样的人有用。
在计划 A 中,如果我们碰巧知道 属性 名称并且到达的顺序根本不重要(只需要这些道具上的单一基数),则所有顶点的遍历可能类似于:
g.V().has(${propname}).where(property(single, ${propname}, properties(${propname}).value().order().tail() ) )
计划B是在同一顶点(例如以_开头)的临时属性名称下收集新的属性值,并遍历具有此类临时属性的顶点命名并使用单基数的尾部值设置原始属性:
g.V().has(${temp_propname}).where(property(single, ${propname}, properties(${temp_propname}).value().order().tail() ) ).properties('temp_propname').drop()
计划 C,这将是最酷的,但不幸的是不起作用,它是在专用顶点中继续收集 属性 值,使用纪元时间戳作为 属性 名称,并且 属性 值作为它们的值:
g.V(${vertexid}).out('has_propnames').properties()
==>vp[1542827843->value1]
==>vp[1542827798->value2]
==>vp[1542887080->latestvalue]
并对 属性 名称(键)进行排序,取最后一个,并使用其值使主顶点 属性 值与最新值保持同步:
g.V().has(${propname}).where(out(${has_these_properties}).count().is(gt(0))).where(property(single, ${propname}, out(${has_these_properties}).properties().value( out(${has_these_properties}).properties().keys().order().tail() ) ) )
看起来 value() 步骤的参数必须是常量,它不能使用另一个遍历的结果作为参数,所以我无法让它工作。也许有更多 Gremlin 经验的人知道解决方法。
读取要从中批量加载的文件并使用顶点 ID 设置 属性 可能会更高效,而不是扫描具有多个值的顶点 属性.
因此您的 gremlin 更新查询如下。
g.V(${id})
.property(single,${key},${value})
至于set是不是保证顺序,我不知道。 :(
AWS 最近在 CSV 批量加载器上引入了 'single' 基数支持: https://docs.aws.amazon.com/neptune/latest/userguide/bulk-load-tutorial-format-gremlin.html 因此,不再需要 Gremlin 级别的 属性 价值安排。