简体   繁体   English

Gremlin / tinkerpop:在遍历的每个顶点和边中插入 key:value 属性常量,然后返回路径

[英]Gremlin / tinkerpop: insert key:value property constant in every vertex and edge traversed then return path

Using AWS Neptune with Gremlin query language (last version).将 AWS Neptune 与 Gremlin 查询语言结合使用(最新版本)。

Using sample data inserted this way:使用以这种方式插入的样本数据:

g.addV('test_report').property('name', 'REF').property('creationDateTime','2022-07-01 00:00:00.000000')
g.addV('test_reportrelease').property('name', 'A').property('creationDateTime','2022-07-01 01:00:00.000000')
g.addV('test_reportrelease').property('name', 'B').property('creationDateTime','2022-07-01 02:00:00.000000')
g.addV('test_reportrelease').property('name', 'C').property('creationDateTime','2022-07-01 03:00:00.000000')

g.addE('test_has').property('creationDateTime','2022-07-02 01:00:00.000000')
.from(V().hasLabel('test_report').has('name', 'REF'))
.to(V().hasLabel('test_reportrelease').has('name', 'A'))

g.addE('test_has').property('creationDateTime','2022-07-02 02:00:00.000000')
.from(V().hasLabel('test_report').has('name', 'REF'))
.to(V().hasLabel('test_reportrelease').has('name', 'B'))

g.addE('test_has').property('creationDateTime','2022-07-02 03:00:00.000000')
.from(V().hasLabel('test_report').has('name', 'REF'))
.to(V().hasLabel('test_reportrelease').has('name', 'C'))

What I want is:我想要的是:

  • First of all, get the vertices with label "test_report"首先,获取标签为“test_report”的顶点
  • then follow all the next statements (union)然后遵循所有接下来的陈述(联合)
  • then follow, if exists, all outgoing edges (outE) with the label "test_has" between vertices with label "test_report" and "test_reportrelease";然后,如果存在,则在带有标签“test_report”和“test_reportrelease”的顶点之间跟踪所有带有标签“test_has”的出边(outE); then follow all ingoing vertices (inV), and apply a constant with name "ref" and value test_has" on every edge browsed然后跟随所有进入的顶点(inV),并在浏览的每条边上应用一个名为“ref”和值 test_has 的常量
  • then follow, if exists, as well the edge "test_has" and ingoing vertices but keep only the first result according to an asc order on creationDateTime, and apply a constant with name "ref" and value "test_first" on every edge browsed然后跟随(如果存在)以及边缘“test_has”和进入顶点,但根据 creationDateTime 上的 asc 顺序仅保留第一个结果,并在浏览的每条边缘上应用名称为“ref”且值为“test_first”的常量
  • then follow, if exists, as well the edge "test_has" but and ingoing vertices keep only the first result according to a desc order on creationDateTime, and apply a constant with name "ref" and value "test_last" on every edge browsed然后跟随(如果存在)以及边缘“test_has”,但进入顶点根据 creationDateTime 上的 desc 顺序仅保留第一个结果,并在浏览的每条边缘上应用名称为“ref”且值为“test_last”的常量
  • then use the tree() step to get all browsed vertices and edges as a tree然后使用 tree() 步骤将所有浏览的顶点和边作为树获取

The main problem is to add the "ref" constant to every edge followed (or change the label at query time).主要问题是将“ref”常量添加到后面的每个边(或在查询时更改标签)。

The sample query I wrote for most of my needs, missing the "ref" constant, is:我为我的大部分需求编写的示例查询缺少“ref”常量,是:

g.V().hasLabel('test_report')
.union(optional(
outE().hasLabel('test_has').order().by('creationDateTime').inV()),
optional(outE().hasLabel('test_has').order().by('creationDateTime').limit(1).inV()),
optional(outE().hasLabel('test_has').order().by(coalesce(values('creationDateTime'), constant('')), desc).limit(1).store('last').inV())
).valueMap(true).path()

Question: How to insert a key:value constant property on every edge or vertex traversed ?问题:如何在遍历的每条边或顶点上插入 key:value 常量属性?

So that the result looks like this (but formatted as a tree - path being more readable when testing):所以结果看起来像这样(但格式化为树 - 测试时路径更易读):

1   path[v[70c0dcd5-a6b9-4532-28bf-85705e94697e], e[66c0dcd7-31ed-e381-5331-e8c73bb91be1][70c0dcd5-a6b9-4532-28bf-85705e94697e-test_has->c0c0dcd5-c102-4031-d739-b5bd8fe161bc], v[c0c0dcd5-c102-4031-d739-b5bd8fe161bc], {<T.id: 1>: 'c0c0dcd5-c102-4031-d739-b5bd8fe161bc', <T.label: 4>: 'test_reportrelease', 'name': ['A'], 'creationDateTime': ['2022-07-01 01:00:00.000000'], 'ref': ['test_has']}]
2   path[v[70c0dcd5-a6b9-4532-28bf-85705e94697e], e[b0c0dcd7-4d99-1f3c-077d-decd2e251c46][70c0dcd5-a6b9-4532-28bf-85705e94697e-test_has->68c0dcd5-c5c5-c869-d789-96acbb88131f], v[68c0dcd5-c5c5-c869-d789-96acbb88131f], {<T.id: 1>: '68c0dcd5-c5c5-c869-d789-96acbb88131f', <T.label: 4>: 'test_reportrelease', 'name': ['B'], 'creationDateTime': ['2022-07-01 02:00:00.000000'], 'ref': ['test_has']}]
3   path[v[70c0dcd5-a6b9-4532-28bf-85705e94697e], e[70c0dcd7-72ac-204f-1341-cc843d165a38][70c0dcd5-a6b9-4532-28bf-85705e94697e-test_has->5ac0dcd5-cb10-f392-7d80-69541c4f22eb], v[5ac0dcd5-cb10-f392-7d80-69541c4f22eb], {<T.id: 1>: '5ac0dcd5-cb10-f392-7d80-69541c4f22eb', <T.label: 4>: 'test_reportrelease', 'name': ['C'], 'creationDateTime': ['2022-07-01 03:00:00.000000'], 'ref': ['test_has']}]
4   path[v[70c0dcd5-a6b9-4532-28bf-85705e94697e], e[66c0dcd7-31ed-e381-5331-e8c73bb91be1][70c0dcd5-a6b9-4532-28bf-85705e94697e-test_has->c0c0dcd5-c102-4031-d739-b5bd8fe161bc], v[c0c0dcd5-c102-4031-d739-b5bd8fe161bc], {<T.id: 1>: 'c0c0dcd5-c102-4031-d739-b5bd8fe161bc', <T.label: 4>: 'test_reportrelease', 'name': ['A'], 'creationDateTime': ['2022-07-01 01:00:00.000000'], 'ref': ['test_first']}]
5   path[v[70c0dcd5-a6b9-4532-28bf-85705e94697e], e[70c0dcd7-72ac-204f-1341-cc843d165a38][70c0dcd5-a6b9-4532-28bf-85705e94697e-test_has->5ac0dcd5-cb10-f392-7d80-69541c4f22eb], v[5ac0dcd5-cb10-f392-7d80-69541c4f22eb], {<T.id: 1>: '5ac0dcd5-cb10-f392-7d80-69541c4f22eb', <T.label: 4>: 'test_reportrelease', 'name': ['C'], 'creationDateTime': ['2022-07-01 03:00:00.000000'], 'ref': ['test_last']}]

I have tried those approaches, but both interrupt the graph traversal when using valueMap:我已经尝试过这些方法,但是在使用 valueMap 时都中断了图遍历:

g.V().hasLabel('test_report').outE().hasLabel('test_has')
.order().by('creationDateTime').limit(1).valueMap(true).unfold().inject(['ref':'test_first']).fold()

And

g.V().hasLabel('test_report').outE().hasLabel('test_has')
.order().by('creationDateTime').limit(1).union(valueMap(true).unfold(), project('ref').by(constant('test_first'))).fold()

Is there a way to achieve such thing ?有没有办法实现这样的事情?

I don't want to have the results stored in the database, just need to have the values in the results.我不想将结果存储在数据库中,只需要在结果中包含值。

PS: I'm querying my graph db from a Jupyter SageMaker Notebook. PS:我正在从 Jupyter SageMaker Notebook 查询我的图形数据库。

Your case sounds somewhat similar to one that came up on the Gremlin Users list recently .您的案例听起来与最近出现在 Gremlin 用户列表中的案例有些相似。

Using the air-routes data set, we can add additional key/value pairs to a result set using a query such as this one.使用 air-routes 数据集,我们可以使用这样的查询向结果集中添加额外的键/值对。

gremlin> g.V().has('code','DAL').
......1>       union(valueMap('city','desc').by(unfold()),
......2>             constant(['special':1234])).unfold().
......3>       group().
......4>         by(keys).
......5>         by(values)

==>[special:[1234],city:[Dallas],desc:[Dallas Love Field]]     

You should be able to use a similar construct in your query.您应该能够在查询中使用类似的构造。 All the query above does is to get some properties and their values from a vertex, and then supplement those using a constant step to add the special key with the 1234 value into the result.上面的所有查询都是从一个顶点获取一些属性及其值,然后使用constant步骤补充这些属性,将具有1234值的special键添加到结果中。 The unfold gives access to each "row" of the map. unfold可以访问地图的每一“行”。 The group builds a new single map containing all three k/v pairs.group构建了一个新的单一地图,其中包含所有三个 k/v 对。

UPDATED更新

Here is a second example that shows how to let the query accumulate the results and do some additional traversing afterwards.这是第二个示例,展示了如何让查询累积结果并在之后进行一些额外的遍历。

gremlin> g.V().has('code','DAL').
......1>     sideEffect(
......2>       union(valueMap('city','desc').by(unfold()),
......3>             constant(['special':1234])).unfold().
......4>       group('x').
......5>         by(keys).
......6>         by(values)).
......7>       project('map','count').
......8>         by(select('x')).
......9>         by(out().count())  

==>[map:[special:[1234],city:[Dallas],desc:[Dallas Love Field]],count:57]   

FURTHER UPDATED进一步更新

To use a sack instead of sideEffect使用sack代替sideEffect

gremlin> g.V().has('code','DAL').
......1>     sack(assign).
......2>       by(union(valueMap('city','desc').by(unfold()),
......3>                constant(['special':1234])).unfold().
......4>          group().
......5>           by(keys).
......6>           by(values)).
......7>       project('map','count').
......8>         by(sack()).
......9>         by(out().count()) 

==>[map:[special:[1234],city:[Dallas],desc:[Dallas Love Field]],count:57]  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM