1

I have a query that I originally wrote in the console:

    g.V().hasLabel('group')
      .has('type', 'PowerUsers')
      .local(__.union(
         __.project('group').by(__.valueMap().by(__.unfold())),
         __.inE().outV().project('user').by(__.valueMap().by(__.unfold())))
      .fold()).unfold().toList()

I get something like:

==>{group={owner=A, group_id=21651399-91fd-4da4-8608-1bd30447e773, name=Group 8, type=PowerUsers}}
==>{user={name=John, user_id=91f5e306-77f1-4aa1-b9d0-23136f57142d}}
==>{user={name=Jane, user_id=7f133d0d-47f3-479d-b6e7-5191bea52459}}
==>{group={owner=A, group_id=ef8c81f7-7066-49b2-9a03-bad731676a8c, name=Group B, type=PowerUsers}}
==>{user={name=Max, user_id=acf6abb8-08b3-4fc6-a4cb-f34ff523d628}}
==>{group={owner=A, group_id=07dff798-d6db-4765-8d74-0c7be66bec05, name=Group C, type=PowerUsers}}
==>{user={name=John, user_id=91f5e306-77f1-4aa1-b9d0-23136f57142d}}
==>{user={name=Max, user_id=acf6abb8-08b3-4fc6-a4cb-f34ff523d628}}

When I run that query with NodeJS, I was expecting to get a similar result, but I don't. I get something like this:

[ { group:
     { owner: 'A',
       group_id: '21651399-91fd-4da4-8608-1bd30447e773',
       name: 'Group 8',
       type: 'PowerUsers' } },
  { user:
     { name: 'John',
       user_id: '91f5e306-77f1-4aa1-b9d0-23136f57142d'} },
  { user:
     { name: 'John',
       user_id: '91f5e306-77f1-4aa1-b9d0-23136f57142d'} },
  { user:
     { name: 'Jane',
       user_id: '7f133d0d-47f3-479d-b6e7-5191bea52459'} },
  { user:
     { name: 'Jane',
       user_id: '7f133d0d-47f3-479d-b6e7-5191bea52459'} },
  { group:
     { owner: 'A',
       group_id: 'ef8c81f7-7066-49b2-9a03-bad731676a8c',
       name: 'Group B',
       type: 'PowerUsers' } },
  { user:
     { name: 'Max',
       user_id: 'acf6abb8-08b3-4fc6-a4cb-f34ff523d628' } },
  ...

Because I have the same users in different groups, I can't use dedup(), and if the results where the same in NodeJS as Groovy, that'd be perfect. Unfortunately, they are not, and I don't understand why the results in NodeJS are all messed up, considering that the query is exactly the same

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
E.T
  • 1,095
  • 1
  • 10
  • 19
  • I think that you need to clarify what is different with these two results. I see that "Jane" is missing in the js results and that "John" is repeated a few times, but I'm not sure I follow the context of why your console results are "right" and the js ones are "wrong". perhaps you should include some sample data as a gremlin script that demonstrates the the expected output. As to why the results are different at all given that they are the same traversal may just have something to do with the non-deterministic ordering of traversers. – stephen mallette Nov 23 '20 at 12:23
  • I made a mistake, the Jane x2 should be there in place of john. I was assuming that the same exact query should show the same results in the console and via Node. Perhaps there are some specific settings that have some default on NodeJS that aren't set on the console? – E.T Nov 24 '20 at 23:02
  • With Gremlin if you want a specific order you should be explicit and use `order()` step to control it. Otherwise, you may get nondeterministic results (depending on the backend). I can't really tell what you really want here as a result which is why i asked for more context. Just using my intuition I would think a different structuring of the result would be better, where the users are directly bound to their groups rather than relying on traversal order but I don't know your requirements. – stephen mallette Nov 25 '20 at 01:59
  • Yes, that's what I meant (poorly explained). What I need is to have the group and then the users, if any, right under it, so that I can know which users belong to what group. With the result I get, I have no way of knowing what groups John and Jane are in. The results from the console is exactly what I need. Now I have to figure out how to order them so that I get the same list. – E.T Nov 26 '20 at 04:15

1 Answers1

2

I feel like you could just use a nested project() to keep your group with your users:

g.V().hasLabel('group')
     .has('type', 'PowerUsers')
     .project('group', 'users')
        .by(__.valueMap().by(__.unfold()))
        .by(__.in().project('user').by(__.valueMap().by(__.unfold()).fold()))

In this way the you don't have to worry about ordering anything. I think it might be more Gremlin-esque though to use the "group" as a key in a Map with the values being a list of users:

g.V().hasLabel('group')
     .has('type', 'PowerUsers')
     .group()
        .by(__.valueMap().by(__.unfold()))
        .by(__.in().project('user').by(__.valueMap().by(__.unfold()).fold()))
stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • I tried both but Neptune doesn't seem to like any. I ended up doing multiple queries instead for now, until I get time to work on this. Thank you, that's quite helpful. – E.T Dec 08 '20 at 22:10
  • Problem with missing ) and I wasn't sure where they went. In this case: g.V().hasLabel('group').has('type', 'PowerUsers').group().by(__.valueMap().by(__.unfold()).by(__.in().project('user').by(__.valueMap().by(__.unfold()).fold()))) would give: {"detailedMessage":"java.util.ArrayList cannot be cast to org.apache.tinkerpop.gremlin.structure.Vertex","requestId":"a341a55c-e76a-4652-91bc-726f68fa5ae4","code":"UnsupportedOperationException"} – E.T Dec 09 '20 at 23:11
  • For this one: g.V().hasLabel('group').has('type', 'PowerUsers').project('group', 'users').by(__.valueMap().by(__.unfold())).by(__.in().project('user').by(__.valueMap().by(__.unfold()).fold())) (after the fixed the parenthesis issue): {"detailedMessage":"The provided traverser does not map to a value: v[20baeed1-7fc0-cb4e-f3ff-bd5f39e2da45]->[VertexStep(IN,vertex), ProjectStep([user],[[PropertyMapStep([[UnfoldStep]],value), NeptuneMemoryTrackerStep, FoldStep]])]","requestId":"e0837f03-e2b2-42eb-9a74-925a9a21d9c8","code":"InvalidParameterException"} – E.T Dec 09 '20 at 23:29
  • i fixed the syntax errors, but i sense something is still wrong. this is why it is always best to provide some sample data in the form of a Gremlin script with your questions as then you get a fully tested traversal back. here is an example https://stackoverflow.com/questions/51388315/gremlin-choose-one-item-at-random – stephen mallette Dec 10 '20 at 12:43
  • note that it's always easy to find syntax errors using a tool like https://gremlify.com/ - the "format" button will help point out problems. – stephen mallette Dec 10 '20 at 12:43
  • Cool! thanks, didn't know about that site. Very helpful – E.T Dec 12 '20 at 00:27