0
votes

There's something I don't get with cypher queries and multiple match.

Context :

target = node(2145) = video game on the app

me = node(2570) = user logged in

I'm trying to get all the users (including me) that interacted with the given target. Furthermore, I want these users to be ordered by distance between them and me...

i.e. The goal is to display the users that interacted with the video game : me and my friends first, and then the others.

My query :

START target=node(2145), me=node(2570)
MATCH (target)-[:INTERACTIONS]->()<-[:IS_TARGET_OF]-(interactions)<-[:IS_SOURCE_OF]-()<-[:INTERACTIONS]-(users)
WITH me, users
MATCH p = (users)-[:CONTACTS]->()-[?:IS_FRIEND_WITH*0..3]-()<-[:CONTACTS]-(me)
RETURN users, MIN(LENGTH(p)) as conn
ORDER BY conn ASC

Issue :

Considering I'm the only one that interacted with the target, I should get one result : 2570.

The issue I have is that I don't see 'me' in the returned users : the query returns nothing

What I tried :

  • If I RETURN right after the first MATCH, I get one result : 2570.
  • if, in the second match, I try p = (users)-[*0..3]-(me), I also get one result : 2570.

  • If I only take the second part of the query to try the following :

    START me=node(2570), users=node(2570, 2802)
    MATCH p = me-[:CONTACTS]->()-[?:IS_FRIEND_WITH*0..3]-()<-[:CONTACTS]-(users)
    RETURN users, MIN(LENGTH(p)) as conn
    ORDER BY conn ASC
    

    I get 2570 and 2802 (because he's my friend).

I'm sure I'm doing something wrong here, but I can't see what..Do you have any idea how I could solve my issue?

Thanks,

1

1 Answers

1
votes

In terms of your experiments, the second pattern match works properly with the "Start". So you might just combine the second match and the first match as a conjunction like this,

START target=node(2145), me=node(2570)
MATCH (target)-[:INTERACTIONS]->()<-[:IS_TARGET_OF]-(interactions)<-[:IS_SOURCE_OF]-()<-[:INTERACTIONS]-(users), p = (users)-[:CONTACTS]->()-[?:IS_FRIEND_WITH*0..3]-()<-[:CONTACTS]-(me)
RETURN users, MIN(LENGTH(p)) as conn
ORDER BY conn ASC  

That should return the node "me" as the result.

As to the reason why the second pattern does not work with the "With" clause, I think the problem is when the "users" and "me" referred to the same node, the pattern becomes to like this,

(me)-[:CONTACTS]->(x)<-[:CONTACTS]-(me)

To match such a pattern, starting from "me", it has to traverse the same relationship to get back to the "me", but the traverse is not supposed to go through the same relationship. So if the "me" and the "users" are the same , then the "me" would not match the second the pattern.

As to why it works with the "start" clause, my speculation is that there would be two traverses starting separately from the two given ending points "users" and "me" and the two meet in the middle to tests the pattern ()-[?:IS_FRIEND_WITH*0..3]-(), so there would not be the problem of traversing the same relationship one more time since they are two separate traverses.