如何在 gremlin 中根据地图内容注入地图和过滤器

How to inject map and filter based on map content in gremlin

我是 运行 JanusGraph 服务器并从 gremlin 控制台连接到它。

可以看出,我有两个顶点,id 属性 设置为 1 和 2

gremlin> g.addV('user').property('id', 1)
==>v[4224]
gremlin> g.addV('user').property('id', 2)
==>v[4192]
gremlin> g.V().valueMap()
==>{id=[2]}
==>{id=[1]}

接下来,我注入了一个具有不同属性的地图数组列表。我试图遍历这张地图并过滤顶点,但我无法弄清楚为什么查询不起作用。有人可以帮我找出正确的查询吗?

我尝试在 select("id") 之后使用终端步骤 next(),但也失败了。

gremlin> g.inject([["id": 1], ["id": 2, "something":"anything"]]).unfold().as("m").V().has("user", "id", select("m").select("id"))
Value [[SelectOneStep(last,m), SelectOneStep(last,id)]] is not an instance of the expected data type for property key [id] and cannot be converted. Expected: class java.lang.Integer, found: class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal
Type ':help' or ':h' for help.
Display stack trace? [yN]

我不能使用 g.V().has(label, key, within(...)),因为我需要在多个地方使用同一张地图并为每一行重复步骤。

尝试以下查询,它应该有效:

g.inject([["id": 1], ["id": 2, "something":"anything"]]).
  unfold().as("m").
  V().
  hasLabel("user").
  has("id", select("m").select("id")).
  dedup()

您的查询失败,因为 has(label, propertyKey, traversal) 语法无效。您可以使用 has(label, propertyKey, propertyValue)has(label, propertyKey, predicate)

在这种情况下,我可能会采用不同的遍历方法并避免 inject()。使用 inject() 你将不得不展开你的 Map 对象列表,然后对每个对象进行顶点查找,如果你的列表很长,这在所有图形系统上可能都很昂贵。我还想知道您是否可以以图形系统能够使用索引优化顶点查找的方式编写遍历。

考虑到所有这些以及您遍历的最终目标是更新找到的顶点的属性,我想我会采用这种方法:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV('user').property('id', 1)
==>v[0]
gremlin> g.addV('user').property('id', 2)
==>v[2]
gremlin> m = [["id": 1], ["id": 2, "something":"anything"]]
==>[id:1]
==>[id:2,something:anything]
gremlin> ids = m.collect{it.id}
==>1
==>2
gremlin> g.withSideEffect('m',m).
......1>   V().has('user','id',within(ids)).as('v').
......2>   sideEffect(select('m').unfold().
......3>              filter(select('id').as('ii').
......4>                     where('ii',eq('v')).
......5>                       by().
......6>                       by('id')).
......7>              unfold().as('kv').
......8>              select('v').
......9>              property(select('kv').by(keys),select('kv').by(values)))
==>v[0]
==>v[2]
gremlin> g.V().elementMap()
==>[id:0,label:user,id:1]
==>[id:2,label:user,id:2,something:anything]

在这里,我们找到所有具有 within() 的顶点作为单个查找,然后 filter() 当前顶点“id” 属性 的数据列表,然后更新属性.