3

I have a query which supposes to join two results and give the union as output.

MATCH (:Some )-[r*0..1]-> (p:Address) WITH collect(p) AS rows1
MATCH (:Some2)-[r*0..1]-> (pp:Address) 
WITH  rows1+collect(pp) AS rows2 
UNWIND rows2 AS row RETURN  row

As you can see the selection has two parts. So it works fine if there is matching data for both queries but if the second part of the match does not return anything then it returns empty. Meaning MATCH (:Some2)-[r*0..1]-> (pp:Address) returns empty then the whole union fails and returns null even if MATCH (:Some )-[r*0..1]-> (p:Address) return values .

How to fix this? Is it a bug in neo4j?

4 Answers 4

2

This simple query should work:

MATCH (s)-[*0..1]->(p:Address)
WHERE s:Some OR s:Some2
RETURN p;
Sign up to request clarification or add additional context in comments.

Comments

0

You have not actually asked a question (you have indeed just described the expected behaviour for pattern matching ... namely that if there is no match there is no result) ... but I assume you want a solution ?

MATCH (:Some )-[r*0..1]-> (p:Address)
RETURN p
UNION
MATCH (:Some2 )-[r*0..1]-> (p:Address)
RETURN p

should do the trick. Note that the only thing that matters is that the variables returned are exactly the same (what they contain doesn't actually matter).

Also ... you might want to have a look at what OPTIONAL MATCH does ...

Hope this helps.

Regards, Tom

Update

CALL apoc.cypher.run("
    MATCH (:Some )-[r*0..1]-> (p:Address)
    RETURN p
    UNION
    MATCH (:Some2 )-[r*0..1]-> (p:Address)
    RETURN p",{}) YIELD value
RETURN value.p AS result
ORDER BY result;

2 Comments

i tried with an optional match .. Is it a bug ? the normal union does not work for me because that does not work with count. I want this to return aggregated count also
Then wrap the whole statement in an apoc.cypher.run and you can postprocess all you want ... I updated my answer to show an example.
0

Thanks for your inputs I used following version

MATCH (p:Address)
WHERE exist ((:Some )-[r*0..1]-> (p)) OR ((:Some2 )-[r*0..1]-> (p))
RETURN p;

Comments

0

I had a very similar problem and this is the answer they gave to me. Basically when you do

// ...
WITH rows1 + collect(pp) AS rows2
// ...

You're involuntarily grouping by rows1, and groups get automatically skipped if they have no element.

If you wanted to change your query as little as possible to do what you wanted, you could just do this

MATCH (:Some)-[r*0..1]->(p:Address)
WITH collect(p) AS rows1
CALL () {
  MATCH (:Some2)-[r*0..1]->(pp:Address)
  RETURN collect(pp) AS rows3
}
WITH rows1 + rows3 AS rows2
UNWIND rows2 AS row
RETURN row

But I advise using one of the better solutions that have already been provided in the other answers

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.