如何在gremlin中注入基于地图内容的地图和过滤器

如何在gremlin中注入基于地图内容的地图和过滤器,gremlin,janusgraph,Gremlin,Janusgraph,我正在运行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]} 接下来,我注入了一个具有不

我正在运行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]}
接下来,我注入了一个具有不同属性的MapArrayList。我试图在这个贴图上循环并过滤顶点,但我不明白为什么查询不起作用。有人能帮我找出正确的问题吗

我尝试在select(“id”)之后使用terminal step 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,propertyValue)
has(label,propertyKey,predicate)

尝试以下查询,它应该可以工作:

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

您的查询失败,因为
的(标签、属性键、遍历)
语法无效。您可以使用
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]

在这里,我们以单个查找的方式找到
位于(
内的所有顶点,然后按当前顶点“id”属性筛选数据列表,然后更新属性。

在这种情况下,我可能会采取不同的遍历方法,避免使用
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]

在这里,我们通过单个查找查找()中的
找到所有顶点,然后通过当前顶点“id”属性筛选数据列表,然后更新属性。

此解决方案无效:(
gremlin>g.V().valueMap()=>{id=[3]}=>{id=[4]}=>{id=[2]}=>{id=[1]}
这给了我所有的4个顶点,而不是两个
gremlin>g.inject([[“id”:1],“id”:2,“something”:“anything”]]).unfold().as(“m”).V().hasLabel(“user”).has(“id”,select(“m”).select(“id”).dedup().valueMap()=>{id=[3]=>{id=[4]}=>{id=[2]=>{id=[1]}
这个解决方案不起作用(
gremlin.g=>=[3] }=>{id=[4]}==>{id=[2]}==>{id=[1]}
这给了我全部4个顶点,而不是两个
gremlin>g.inject([[id]:1],“id”:2,“something”:“anything”]]]].unfold().as(“m”).hasLabel(“user”).has(“id”,select(“m”).select”(“id”).select”).dedup().valueMap()=>{id=>{id=[4]=>
被误解得很厉害。这是为了过滤那些不能通过属性值的遍历产生结果的遍历器。这并不是说将
select(“m”).select(“id”)
的结果注入
has()
并使用该值确定过滤器是否有效。使用该
映射的最终目标是什么?@stephenmallette最终目标是能够操纵几个顶点。假设输入为
[[“id”:1,“something”:“anything1”],[“id”:2,“something”:“anything2”]]
然后我希望能够一次完成以下操作->查找id为“1”的用户顶点,然后转到公司(学院)用户为该顶点工作并在该顶点上添加任何属性1。->查找id为“2”的用户顶点,然后转到公司(学院)用户为该顶点工作并在该顶点上添加任何属性2。@stephenmallette
有(…,遍历)
被误解得很厉害。这是为了过滤那些不能通过属性值的遍历产生结果的遍历器。这并不是说将
select(“m”).select(“id”)
的结果注入
has()
并使用该值确定过滤器是否有效。使用该
映射的最终目标是什么?@stephenmallette最终目标是能够操纵几个顶点。假设输入为
[[“id”:1,“something”:“anything1”],[“id”:2,“something”:“anything2”]]
然后我希望能够一次完成以下操作->查找id为“1”的用户顶点,然后转到用户工作的公司(学院)并在该顶点上添加任何属性1。->查找id为“2”的用户顶点,然后转到公司(学院)用户为顶点anything2工作并在其上添加属性。@StephenMallette感谢您的回答。我不希望地图的大小很大,可能是~10行。此解决方案解决了我原来的问题,但在我的情况下,可能会有重复的条目。
[[“id”:1],“id”:2,“something”:“anything”],[“id”:1,“something1”:“anything2]”
基本上,每个贴图都包含一系列需要应用的指令,不仅是在该顶点上,而且是在其相邻点上。这使得我很难预处理和合并条目,或者在其中使用。不过,您的解决方案解决了我原来的问题。我想您只需要使用
inject()
正如您所做的那样,这样您就可以为每个
映射获得一个遍历器