cancel
Showing results for 
Search instead for 
Did you mean: 

Strange results using UNION

paolodipietro58
Graph Voyager

Neo4j Commmunity edition 4.3.3, Ubuntu 20.04

I have a question: in my head, the following queries should returns the same value, but they don't:

      CALL {
            MATCH (recipe:Recipe {uuid: "ee35d995-bcac-46f9-aeda-2bffc7a29dfa"})<-[:CAN_BE_SUGGESTED_FOR]-(mention:Mention)
                RETURN mention, recipe
            UNION
                MATCH (recipe:Recipe {uuid: "ee35d995-bcac-46f9-aeda-2bffc7a29dfa"})-[:HAS_TRADITIONAL_WINE]->(mention:Mention)
                RETURN mention, recipe
        }
            WITH recipe, mention

         RETURN recipe, mention
       CALL {
            MATCH (recipe:Recipe {uuid: "ee35d995-bcac-46f9-aeda-2bffc7a29dfa"})<-[:CAN_BE_SUGGESTED_FOR]-(mention:Mention)
                RETURN mention, recipe
            UNION
                MATCH (recipe)-[:HAS_TRADITIONAL_WINE]->(mention:Mention)
                RETURN mention, recipe
        }
            WITH recipe, mention

         RETURN recipe, mention

The only difference is that in the second query I removed the explicit uuid because I want to reuse the previously matched recipe. But the first query returns 94 mention, while the 2nd returns 96.

It looks like the second query attach any recipe with -[d:HAS_TRADITIONAL_WINE]->(mention:Mention) while I expected it to reuse the exact recipe node from the previous MATCH.

Where is my fault? Can anyone help to understand the problem?

1 ACCEPTED SOLUTION

Sure, the problem is that the variables used in UNIONed queries are independent. The recipe you match to in the first part of the UNION is not visible or reused in the second part, so in the second part is viewed as an entirely new variable recipe, not the specific one you matched to earlier. The second query will start from every :Mention node and return every node that has a traditional wine mentioned.

In order to reuse the variable, you should MATCH to the recipe outside of the subquery call and pass it in so it is visible from both parts of the UNION:

MATCH (recipe:Recipe {uuid: "ee35d995-bcac-46f9-aeda-2bffc7a29dfa"})
CALL {
    WITH recipe
    MATCH (recipe)<-[:CAN_BE_SUGGESTED_FOR]-(mention:Mention)
    RETURN mention, recipe
  UNION
    WITH recipe 
    MATCH (recipe)-[:HAS_TRADITIONAL_WINE]->(mention:Mention)
    RETURN mention, recipe
}
RETURN mention, recipe

View solution in original post

1 REPLY 1

Sure, the problem is that the variables used in UNIONed queries are independent. The recipe you match to in the first part of the UNION is not visible or reused in the second part, so in the second part is viewed as an entirely new variable recipe, not the specific one you matched to earlier. The second query will start from every :Mention node and return every node that has a traditional wine mentioned.

In order to reuse the variable, you should MATCH to the recipe outside of the subquery call and pass it in so it is visible from both parts of the UNION:

MATCH (recipe:Recipe {uuid: "ee35d995-bcac-46f9-aeda-2bffc7a29dfa"})
CALL {
    WITH recipe
    MATCH (recipe)<-[:CAN_BE_SUGGESTED_FOR]-(mention:Mention)
    RETURN mention, recipe
  UNION
    WITH recipe 
    MATCH (recipe)-[:HAS_TRADITIONAL_WINE]->(mention:Mention)
    RETURN mention, recipe
}
RETURN mention, recipe
Nodes 2022
Nodes
NODES 2022, Neo4j Online Education Summit

On November 16 and 17 for 24 hours across all timezones, you’ll learn about best practices for beginners and experts alike.