5

What is the best way to get values with same property key?

EDIT: Sorry for changing the question my requirement was to get an employee from either of the departments

I need to fetch all the the employees who work for IT or Sales departments and are being managed by manager with id 123.

I have used

g.V().has('managerId',123).out('manages').as('employee')
   .out('worksFor').has('departmentName','IT','Sales')
   .select('employee')

where out('worksAt') gives department.

Can we do this in a has() step or should we use union() step like

g.V().has('managerId',123).out('manages').as('employee').out('worksFor')
    .union(__.has('departmentName','IT'),__.has('departmentName','Sales')
    .select('employee')
Mahi Tej Gvp
  • 984
  • 1
  • 14
  • 34

2 Answers2

7

You are probably only missing the within predicate which is also explained in the context of the has step in the TinkerPop documentation:

g.V().has('managerId',123).out('manages').as('employee').out('worksFor').
    has('departmentName',within('IT','Sales')).select('employee')

edit: After reading stephen's answer I noticed that I read over the and in your question:

employees who work for IT and Sales

That makes my answer of course invalid. I still leave it here just in case that you actually meant or as indicated by your later use of the union step.

Florian Hockmann
  • 2,634
  • 13
  • 24
  • Hey! How can I query on gremlin-python within method? – Berkay Jun 25 '21 at 20:32
  • 1
    It should work exactly the same way with gremlin-python. You probably just need [some imports](https://tinkerpop.apache.org/docs/current/reference/#gremlin-python-imports). – Florian Hockmann Jun 29 '21 at 10:54
6

Here's a sample graph:

gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV("managerId",123).as("manager").
......1>   addV("employee","A").as("A").
......2>   addV("employee","B").as("B").
......3>   addV("department", "IT").as("it").
......4>   addV("department", "Sales").as("sales").
......5>   addE("manages").from("manager").to("A").
......6>   addE("manages").from("manager").to("B").
......7>   addE("worksFor").from("A").to("it").
......8>   addE("worksFor").from("B").to("it").
......9>   addE("worksFor").from("A").to("sales").iterate()

In this case, I make it so that employee A is in both "Sales" and "IT", but employee B is only in "IT". Since you said you wanted employees who work in both departments employee A is who should be returned from the query and B should be filtered out.

Note that the use of within yields an incorrect answer in that case:

gremlin> g.V().has('managerId',123).
......1>   out('manages').
......2>   where(out('worksFor').
......3>         has('department',within('IT','Sales'))).
......4>   valueMap()
==>[employee:[A]]
==>[employee:[B]]

Here is the approach if you want both departments:

gremlin> g.V().has('managerId',123).
......1>   out('manages').
......2>   where(out('worksFor').
......3>         has('department','Sales')).
......4>   where(out('worksFor').
......5>         has('department','IT')).
......6>   valueMap()
==>[employee:[A]]
stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • Thank you Stephen I have a small doubt can't I use has() step twice to get the same result – Mahi Tej Gvp Feb 25 '17 at 12:41
  • How ever my requirement was to get all the employees who work either for IT or Sales – Mahi Tej Gvp Feb 25 '17 at 12:42
  • 1
    Then Florian Hockmann posted the right answer originally, though i would prefer my answer that uses `within` as you get rid of the `as('employee')` and `select('employee')`. imo, the use of `where` is easier to read/comprehend at a glance. – stephen mallette Feb 25 '17 at 13:44