cancel
Showing results for 
Search instead for 
Did you mean: 

Query with multiple common ancestors

leelandclay
Graph Buddy

I'm working on refactoring my model to move the country, city and state properties out of my :Person node and into their own nodes. All that's left is rewriting the queries to pull the information from the proper location. Everything was going well until I got to a search query (which actually began this process).

My model now looks like this:

(:Person)-[:LIVES_IN]->(:City)-[:LOCATED_IN]->(:State)-[:LOCATED_IN]->(:Country)

I ran the old query and got the output to compare. The old query got 161 results and the new one only got 105. I exported results and started comparing and discovered that the items that aren't showing up share a :State node.

The query I'm using is:

MATCH (me:Person { userId: $userId }) 
MATCH (me)-[:LIVES_IN]->(:City)-[:LOCATED_IN]->(:State)-[:LOCATED_IN]->(:Country)<-[:LOCATED_IN]-(:State)<-[:LOCATED_IN]-(:City)<-[:LIVES_IN]-(p) 
WHERE p.distance = 999 OR ( p.distance < 998 AND (p.distance * 1609.34) > distance(me.location, p.location) ) 

In order to find the problem, I shortened the query down to:

MATCH (me:Person {userId: 'YKh3tLHKfmQ33ugw7tKoGVa6Sg42'})-[:LIVES_IN]->(:City)-[:LOCATED_IN]->(:State)-[:LOCATED_IN]->(:Country)<-[:LOCATED_IN]-(:State)<-[:LOCATED_IN]-(:City)<-[:LIVES_IN]-(p:Person {userId: '1pttqqFOrXcjRdBLTNFP9RywP3W2'}) return me, p

I pulled up each of the Person objects and verified that they followed up to the same State and Country by checking the ids of the State and Country nodes. My guess is that it's getting tripped up by being in the same state...but I'm not sure. As a test, I removed the Country part and it returned both of the nodes as expected. Is there something I need to do to allow it to find matches for both country and state???

1 REPLY 1

leelandclay
Graph Buddy

After a lot of trial and error, I couldn't figure out a way to get the match to work as written, so I modified it to instead get the country and state of the caller and use that in a second match statement like so:

MATCH (me:Person { userId: $userId }) 
MATCH (me)-[:LIVES_IN]->(:City)-[:LOCATED_IN]->(s:State)-[:LOCATED_IN]->(c: Country)
MATCH (:Country {short_name: c.short_name})<-[:LOCATED_IN]-(:State)<-[:LOCATED_IN]-(:City)<-[:LIVES_IN]-(p) 
WHERE p.distance = 999 OR ( p.distance < 998 AND (p.distance * 1609.34) > distance(me.location, p.location) ) 
OR (p.distance = 1000 AND SIZE( (s)<-[:LOCATED_IN]-(:City)<-[:LIVES_IN]-(p)) = 1) 
RETURN p

Not sure if that's the best way...but it's working 🙂

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.