0

So I have a graph schema where vertex type A can connect inwards to vertex type B or type C in a one to many relationship. I'm trying to write a query that outputs any of those relationships if they exist, for instance a sample output would be:

Type A | Type B | Type C
Sample1A,'', Sample1C
Sample2A, Sample2B, ''
Sample3A, Sample3B, Sample3C
Sample4A, 'Sample4Ba, Sample4Bb', Sample4C

The fourth example is if A is connected to multiple B types. If B and C don't exist, then nothing is output.

So far I have the query: g.V().hasLabel('A').as('A').in('connect').hasLabel('B').as('B').or().in('connect').hasLabel('C').as('C').select('A','B','C')

But this query only returns the A vertices without any B's or C's.

Using AWS Neptune if that matters.

dl8
  • 1,270
  • 1
  • 14
  • 34

2 Answers2

1

Your or() steps are not returning a result as written. You could simplify the query as follows:

g.V().hasLabel('A').as('A').in('connect').hasLabel(within('B','C').as('B').select('A','B')

This avoids using select('A','B','C') as only one of 'B' or 'C' will have a result in the or() case.

Here is a version that still uses or()

g.V().hasLabel('A').as('A').in().or(hasLabel('B'),hasLabel('C')).as('B').select('A','B')
Kelvin Lawrence
  • 14,674
  • 2
  • 16
  • 38
  • So your suggested queries outputs the vertices as two variables, A or B. I would want something like the output in my original post that would output the results as three potential variables: if B and C both exists it would also output those two. And if only one exists it would specify which one it is. – dl8 Oct 07 '19 at 18:40
  • 1
    To do that you probably need to change to a project('a','b','c') construction where for 'b' and 'c' you use something like coalesce to generate either a value or a constant such as 'none'. I can try to show a sample query later. – Kelvin Lawrence Oct 08 '19 at 22:18
  • I think coalesce will produce the first result that is returning the value in the order. So if both B and C is available, it might not display both. – ashoksl Oct 09 '19 at 10:15
1

As kevin mentioned in the comment, you can use .project() method for this scenario.

g.V().hasLabel("A").as("A").project("a","b", "c")
    .by(select("A"))
    .by(choose(in("connect").hasLabel("B").count().is(0), constant("NO_B").value(), in("connect").hasLabel("B")))
    .by(choose(in("connect").hasLabel("C").count().is(0), constant("NO_C").value() , in("connect").hasLabel("C")));
ashoksl
  • 383
  • 6
  • 17
  • Hmm having issues with the "in" steps. I get unexpected token errors. Still get the same error if I use "in_" as well. – dl8 Oct 09 '19 at 18:11
  • I believe it's the second "in" (the else statement) in each by step that's causing the issue. – dl8 Oct 09 '19 at 18:19
  • Ah figured it out, the second "in"s must be "__.in – dl8 Oct 09 '19 at 18:20