How can I add to the map produced by .valueMap()?

335 views
Skip to first unread message

Daniel Craig

unread,
Jun 27, 2022, 12:54:35 PM6/27/22
to Gremlin-users
I want to do a .valueMap() and add an additional key and value to the result.  Is this possible?

Kelvin Lawrence

unread,
Jun 28, 2022, 10:06:26 AM6/28/22
to Gremlin-users
The best way to do this, or at least a reasonable way, is to use a project step coupled with a value map I would think. I'll mock up an example and share in a follow up post.
Message has been deleted

Kelvin Lawrence

unread,
Jun 28, 2022, 10:23:06 AM6/28/22
to Gremlin-users
Using the air-routes data set. Let's imagine we want some values from the DAL airport, but also want to add an additional k/v pair to the result. A first step might be to create two maps like this:

g.V().has('code','DAL').
      project('map','extra').
        by(has('code','DAL').valueMap('city','desc').by(unfold())).
        by(constant(['special':1234]))


Which results in

{'map': {'city': 'Dallas', 'desc': 'Dallas Love Field'}, 'extra': {'special': 1234}}

we can go one step further and create a single map as follows

g.V().has('code','DAL').
      project('map','extra').
        by(valueMap('city','desc').by(unfold())).
        by(constant(['special':1234])).
        union(
           select('map').unfold().unfold(),
           select('extra').unfold().unfold()).
        group().
          by(keys).
          by(values)


Which gives

{'special': [1234], 'city': ['Dallas'], 'desc': ['Dallas Love Field']}

There are other ways this query could be written. I did this quite quickly, I'll think about ways to make it a bit simpler, but hopefully this gives you some useful pointers.

Kelvin Lawrence

unread,
Jun 28, 2022, 11:33:31 AM6/28/22
to Gremlin-users
Having thought about this some more, as it was bugging me that my first solution felt too complex, here is a simpler alternative:

g.V().has('code','DAL').
      union(valueMap('city','desc').by(unfold()),
            constant(['special':1234])).unfold().
      group().
        by(keys).
        by(values)


Daniel Craig

unread,
Jun 28, 2022, 10:08:54 PM6/28/22
to Gremlin-users
Thank you Kelvin!!

Daniel Craig

unread,
Jun 30, 2022, 12:00:29 PM6/30/22
to Gremlin-users
Could you explain what keys and values are?  These appear to be available to me in gremlin-console by I am struggling to replicate them in on the Java side.

Arthur Bigeard

unread,
Jun 30, 2022, 12:22:52 PM6/30/22
to Gremlin-users
Have you tried Column.keys? (import org.apache.tinkerpop.gremlin.structure.Column)

Daniel Craig

unread,
Jun 30, 2022, 2:32:41 PM6/30/22
to Gremlin-users

Column.keys gives me The provided object does not have accessible keys: class java.lang.String

Here is my query:
(traverse g
            (V "KDAL")
            (union
             (__ (value-map "iataCode" "icaoCode")
                 (by (__ (unfold))))
             (__ (constant ["Key" "Value"])))
            (unfold)
            (group)
            (by Column/keys)
            (by Column/values)
            (into-seq!))

Note that g.V("KDAL").union(__.valueMap("iataCode", "icaoCode").by(__.unfold()), constant(["key": "value"])).unfold().group().by(keys).by(values) works correctly.

Daniel Craig

unread,
Jun 30, 2022, 3:15:00 PM6/30/22
to Gremlin-users
With a little more work and the help of this Stack Overflow answer, I got something working: https://stackoverflow.com/a/50773496

Here is my query:
(traverse g
            (V "KDAL")
            (union
             (__ (value-map "iataCode" "icaoCode")
                 (by (__ (unfold))))
             (__ (constant {"key" "value"}))
             )
            (unfold)
            (group)
            (by (__ (select Column/keys)))
            (by (__ (select Column/values)))
            (next!))

Daniel Craig

unread,
Jun 30, 2022, 5:06:29 PM6/30/22
to Gremlin-users
Now instead of a constant, I need to project a child vertex; is this possible?

Kelvin Lawrence

unread,
Jul 6, 2022, 12:21:22 PM7/6/22
to Gremlin-users
Yes - just replace the constant with something like by(out('somelabel'))

John Walthour

unread,
Dec 9, 2022, 3:47:23 AM12/9/22
to Gremlin-users
Hi Kelvin!  I'm trying to solve a similar problem, and this thread was super helpful.  Can you elaborate on your last message?  I'm a bit new to Gremlin, and I'm trying to figure out how to turn something like `by(out('somelabel'))` into a key/value pair.


Personally, i'm trying to insert an edge count into the properties returned by `valueMap()`.  (without editing the properties on that vertex in the underlying graph)  I successfully ran a derivative of your comment above:

(this is with gremlin-python)
```
(
    g
    .V(node_id)
    .union(
        valueMap().by(unfold()),
          constant({'special':1234})
    )
    .unfold()
    .group()
        .by(keys)
        .by(values)
    .next()
)
```

And that worked.   I want to replace that `constant({'special':1234})` section with a key-value pair like `{'edge_count': __.bothE().count()}`, but I can't figure out how to get the gremlin syntax right.  Any ideas?

Thanks!
Reply all
Reply to author
Forward
0 new messages