Using UNWIND to generate multiple MATCH statements

I have a query like this:

CALL(){
MATCH (:account {name:"A"})<-[:BELONGS_TO]-(m),(:account {name:"B"})<-[:BELONGS_TO]-(m)
RETURN m
}
MATCH path = (p {name:"bob"}) - [r] -> (m)
      RETURN path
      ORDER BY r.distance
      LIMIT 10

This effectively filters my graph to include only data from accounts A and B.

The list of accounts will be dynamic and can have different lengths.

Is there a way to rewrite this query using UNWIND?

I'm new to Cypher. I tried this, but it produces duplicate rows. It's clearly not correct.

CALL(){
UNWIND ["A","B"] as acc
MATCH (:account {name:acc})<-[:BELONGS_TO]-(m)
RETURN m
}
MATCH path = (p {name:"bob"}) - [r] -> (m)
            RETURN path
            ORDER BY r.distance
            LIMIT 10

Thanks in advance,
Kyle

I just realized my first query doesn't actually do what I thought it did. It's effectively an AND, and I need an OR

Can you describe what is the graph and what is the outcome of the query? :)

Hi Josh

Here is the schema:

Jobs and Courses can belong to multiple accounts.

I need to be able to filter the graph by account(s).

Let's say I have accounts A, B, C, and D.

Bob is a member of accounts A and B.

I want to display the top jobs and courses available in accounts A and B based on the distance from Bob to Course or Job.

My latest attempt looks like this:

MATCH (a:account)<-[:BELONGS_TO]-(m)
WHERE any(acc IN ["A","B"] WHERE a.name = acc)
MATCH path = (p {name:"bob"}) - [r] -> (m)
            RETURN path
            ORDER BY r.distance
            LIMIT 10

But this gives me duplicates. I believe it's because these jobs belong to multiple accounts:

(:user {name: "bob"})-[:HAS_PATH_TO {distance: 0.8450704225352113}]->(:job {name: "Educational Institute Director"})

(:user {name: "bob"})-[:HAS_PATH_TO {distance: 0.8450704225352113}]->(:job {name: "Educational Institute Director"})

(:user {name: "bob"})-[:HAS_PATH_TO {distance: 0.8571428571428572}]->(:job {name: "Chairperson of the Board of Directors"})

(:user {name: "bob"})-[:HAS_PATH_TO {distance: 0.8571428571428572}]->(:job {name: "Chairperson of the Board of Directors"})

(:user {name: "bob"})-[:HAS_PATH_TO {distance: 0.8615384615384616}]->(:job {name: "Primary School Headmaster"})

(:user {name: "bob"})-[:HAS_PATH_TO {distance: 0.8615384615384616}]->(:job {name: "Primary School Headmaster"})

(:user {name: "bob"})-[:HAS_PATH_TO {distance: 0.8666666666666667}]->(:job {name: "Primary School Deputy Headmaster"})

...

Did you try with DISTINCT?

1 Like

yes. It gives this syntax error:

In a WITH/RETURN with DISTINCT or an aggregation, it is not possible to access variables declared before the WITH/RETURN: r (line 5, column 22 (offset: 209))
"            ORDER BY r.distance"
                      ^

actually, just moving the ORDER BY above the return works.

So the query looks like this now:

MATCH (a:account)<-[:BELONGS_TO]-(m)
WHERE any(acc IN ["A","B"] WHERE a.name = acc)
MATCH path = (p {name:"bob"}) - [r] -> (m)
     ORDER BY r.distance            
     RETURN DISTINCT path
     LIMIT 10

Thanks a million!

1 Like