Neo4j match don't return rows - neo4j

I work with neo4j cypher
I have two relations
MATCH (user)-[:CreatesChat]-(chatitems)
MATCH (chatitems)-[:PartOf]->(teamsChat)-[:OwnedBy]-()
With the first query I got the users and chatitems.
And with the second query I got the teams.
I want to check if the users first query have the teams of the second query.
I wrote this query
MATCH (user)-[:CreatesChat]-(chatitems)
WITH user as users ,chatitems as chats ORDER BY chatitems.id DESC LIMIT 10
WITH users,collect(chats) AS chats1
with users, chats1, collect(users) as users1
MATCH (chatitems)-[:PartOf]->(teamsChat)-[:OwnedBy]-()
WITH users1, chats1,teamsChat ORDER BY teamsChat.id DESC LIMIT 3
WITH users1, chats1, collect(teamsChat) AS teams
UNWIND teams AS team
UNWIND chats1 AS chatid
unwind users1 as userid
return userid, chatid, team
Results are
userid,chatid,team
"{""id"":789}","{""id"":65090}","{""id"":62531}"
"{""id"":789}","{""id"":65090}","{""id"":62531}"
"{""id"":656}","{""id"":65092}","{""id"":62531}"
To check if users have the teams of second match, I added
MATCH (user)-[:CreatesChat]-(chatitems)
WITH user as users ,chatitems as chats ORDER BY chatitems.id DESC LIMIT 10
WITH users,collect(chats) AS chats1
with users, chats1, collect(users) as users1
MATCH (chatitems)-[:PartOf]->(teamsChat)-[:OwnedBy]-()
WITH users1, chats1,teamsChat ORDER BY teamsChat.id DESC LIMIT 3
WITH users1, chats1, collect(teamsChat) AS teams
UNWIND teams AS team
UNWIND chats1 AS chatid
unwind users1 as userid
MATCH p=(chats)-[:PartOf]-(teams)-[:OwndedBy]-(users)
RETURN p
This query returns no rows.
How do I have to use the users1,chats1 and team that I got before in MATCH
MATCH p=(chats)-[:PartOf]-(teams)-[:OwndedBy]-(users)
EDITED:
I checked some queries.
I have the query(chatitems and teams)
MATCH (chatitems1)-[:PartOf]->(teamsChat)-[:OwnedBy]-()
WITH chatitems1 , teamsChat ORDER BY teamsChat.id DESC LIMIT 3
return chatitems1,teamsChat
chatitems1,teamsChat
"{""id"":64990}","{""id"":62531}"
"{""id"":63247}","{""id"":62531}"
"{""id"":60211}","{""id"":58852}"
After I executed the query
MATCH (user)-[:CreatesChat]-(chatitems)
WITH user ORDER BY user.id DESC LIMIT 10
MATCH (chatitems1)-[:PartOf]->(teamsChat)-[:OwnedBy]-()
WITH user,chatitems1 , teamsChat ORDER BY teamsChat.id DESC LIMIT 3
return user,chatitems1,teamsChat
I want to see users query 1 and chatitems, teamsChats query 2. The result is
user,chatitems1,teamsChat
"{""id"":65098}","{""id"":64990}","{""id"":62531}"
"{""id"":65098}","{""id"":63247}","{""id"":62531}"
"{""id"":65097}","{""id"":64990}","{""id"":62531}"
Do neo4j a product cartesian?

Related

Difference between the results of two independent queries neo4j

I have 2 subqueries that returns 2 sets of users (each query return one set of users)
First query :
MATCH (:User {user_id: "69b3315a-ba4a-4021-94e1-0f494f9b957f"})-->(first_set_of_users)
RETURN first_set_of_users
Second query :
MATCH (:User {user_id: "69b3315a-ba4a-4021-94e1-0f494f9b957f"})<-[:LIKES]-(likers)-[:LIKES]->(v)
WITH DISTINCT v
MATCH (second_set_of_users)-[:LIKES]->(v)
RETURN second_set_of_users, COUNT(*) AS recoWeight
ORDER BY recoWeight DESC
What I want to finally return is all users from second_set_of_users minus the one in first_set_of_users and ORDER BY recoWeight DESC
How can I do that in just one query ? Everything I tried led to cartesian products of queries and took forever while each independent query takes less than a second.
MATCH (:User {user_id: "69b3315a-ba4a-4021-94e1-0f494f9b957f"})-->(first_set_of_users)
WITH collect(first_set_of_users) AS list_of_first_set_of_users
MATCH (:User {user_id: "69b3315a-ba4a-4021-94e1-0f494f9b957f"})<-[:LIKES]-(likers)-[:LIKES]->(v)
WITH DISTINCT v, list_of_first_set_of_users
MATCH (second_set_of_users)-[:LIKES]->(v)
WITH second_set_of_users, COUNT(*) AS recoWeight
WHERE NOT second_set_of_users IN list_of_first_set_of_users
RETURN second_set_of_users, recoWeight
ORDER BY recoWeight DESC
Explanation.
Using WITH clause we could pass the result of the first query into the second query.
And then using WHERE NOT IN we could filter the result of the second query.

neo4j how to count distinct relationships group by node?

I have a graph db of Node User (properties: uid, name) and Relationship Invitation (properties: invitation_id, invitation_time).
The relationship is built when one user invite other users. That means every time one user invites, it will build the same relationship between him and the users he invited.
I want to count the unique invitations of each user.
My cyper query is:
match (u:User)-[r:Invitation]->()
return u, count(distinct r)
order by count(distinct r) desc
Instead of meet my expectation, this query did not drop the duplicates.
So what should be the right query?
I got the answer by myself just after posting the question:
match (u:User)-[r:Invitation]->()
return u, count(distinct r.invitation_id)
order by count(distinct r.invitation_id) desc

neo4j how to work with two match

I have two queries.
First query is
match (user)-[r:CreatesChat]-(chatitems)
Second query is
match (chatitems)-[r:PartOf]-(teamschat)-[s:OwnedBy]-()
I want to return the first 3 users from the first query
And to return the first 3 teams from the second query
The goal is to check if users from first query have the teams of second query
My neo4j query is
match (user)-[r:CreatesChat]-(chatitems)
with user.id as uid,chatitems.id as chatid
order by uid desc
with collect([uid])[..3] as users,collect([chatid])[..3] as chats
UNWIND users AS idusers
match (chatitems)-[r:PartOf]-(teamschat)-[s:OwnedBy]-()
return idusers
This query return
Returned 133239 rows in 1360 ms, displaying first 1000 rows
But I execute the query
match (user)-[r:CreatesChat]-(chatitems)
with user.id as uid,chatitems.id as chatid
order by uid desc
with collect([uid])[..3] as users,collect([chatid])[..3] as chats
UNWIND users AS idusers
return idusers
idusers returned are right
Returned 3 rows in 539 ms.
How can I relate these two queries ?
I think you want to collect both the top 3 users and the top 3 teams and then unwind over each collection. Something like this:
MATCH (user:User)-[:CreatesChat]->(chatitems:Chat)
WITH user ORDER BY user.id DESC LIMIT 3
WITH collect(user) AS users
MATCH (chatitems:Item)-[:PartOf]->(teamsChat:Team)-[:OwnedBy]-()
WITH users, teamsChat ORDER BY teamsChat.id DESC LIMIT 3
WITH users, collect(teamsChat) AS teams
UNWIND users AS user
UNWIND teams AS team
MATCH p=(chatitems:Item)-[:PartOf]-(team)-[:OwndedBy]-(user)
RETURN p

Distinct nodes in multiple MATCH query

I have a movie database with users rating movies. I want to find the top 5 most similar users to user 1 (first MATCH which works fine) and recommend him the top rated movies watched by those similar users but not watched by user 1. I get the same movie multiple times even though I have "distinct" in my query. What am I doing wrong?
MATCH (target_user:User {id : 1})-[:RATED]->(m:Movie)
<-[:RATED]-(other_user:User)
WITH other_user, count(distinct m.title) AS num_common_movies, target_user
ORDER BY num_common_movies DESC
LIMIT 5
MATCH other_user-[rat_other_user:RATED]->(m2:Movie)
WHERE NOT (target_user-[:RATED]->m2)
WITH distinct m2.title as movietitle, rat_other_user.note AS rating,
other_user.id AS watched_by
RETURN movietitle, rating, watched_by
ORDER BY rating DESC
You dataset probably has many users who have watched and rated the same movies. When you execute that DISTINCT statement it is going to return a distinct row, not a distinct movie title. Different users will have rated the unwatched movies differently and have different names.
You will have to tune this for your particular use case but you can start from:
MATCH (target_user:User { uid : 1 })-[:RATED]->(m:Movie)<-[:RATED]-(other_user:User)
WITH other_user, count(DISTINCT m.title) AS num_common_movies, target_user
ORDER BY num_common_movies DESC
LIMIT 5
MATCH other_user-[rat_other_user:RATED]->(m2:Movie)
WHERE NOT (target_user-[:RATED]->m2)
RETURN DISTINCT m2.name AS movietitle, COLLECT(rat_other_user.note) AS ratings,
MAX(rat_other_user.note) AS maxi, AVG(rat_other_user.note) as aver, COLLECT(other_user.name) AS users
ORDER BY aver DESC
I added a console demo here.
Importantly the you are now aggregating your results per movie title.

Issue combining two cypher queries with UNION

I ran into the following problem when combining two cypher queries on console.neo4j.org
The query:
MATCH (p1:Crew)-[r_pfq]->(fq:Crew)
WHERE fq.name IN ["Neo", "Morpheus"]
RETURN distinct(p1) AS person, count(r_pfq) AS friend_score, collect(fq.name) AS friends
ORDER BY friend_score DESC
LIMIT 10
works fine, as does
MATCH (f:Crew)<-[r_fqf]-(fq:Crew)
WHERE fq.name IN ["Neo", "Morpheus"]
WITH distinct(f), count(r_fqf) AS weight
ORDER BY weight DESC
LIMIT 10
MATCH f<--(p:Crew)
RETURN distinct(p) AS person, sum(weight) AS friend_score, collect(f.name) AS friends
ORDER BY friend_score DESC
LIMIT 10
Now when I try to combine the query results using the UNION command, i.e.
MATCH (p1:Crew)-[r_pfq]->(fq:Crew)
WHERE fq.name IN ["Neo", "Morpheus"]
RETURN distinct(p1) AS person, count(r_pfq) AS friend_score, collect(fq.name) AS friends
ORDER BY friend_score DESC
LIMIT 10
UNION
MATCH (f:Crew)<-[r_fqf]-(fq:Crew)
WHERE fq.name IN ["Neo", "Morpheus"]
WITH distinct(f), count(r_fqf) AS weight
ORDER BY weight DESC
LIMIT 10
MATCH f<--(p:Crew)
RETURN distinct(p) AS person, sum(weight) AS friend_score, collect(f.name) AS friends
ORDER BY friend_score DESC
LIMIT 10
I get the error
Error: org.neo4j.graphdb.NotFoundException: Unknown identifier `weight`.
Can anyone provide me with an explanation why these query results can not be combined and how to properly do so? Why is the identifier known when running both queries separately but unknown in a UNION-combined query?
EDIT
The following simpler query is basically equivalent, except that the second query in the UNION does not ORDER BY weight. This is because we are already ordering by the derived friend_score, so it seemed redundant. Also, in order for a variable to be included in the ORDER BY clause, it has to be in the RETURN clause -- but the first query in the UNION does not have a weight variable, which would have violated the requirements for a legal UNION statement.
In addition, there is a second WITH clause in the second query because you have to define the variables used in an ORDER BY clause (like friend_score) before the RETURN clause!
MATCH (p1:Crew)-[r_pfq]->(fq:Crew)
WHERE fq.name IN ["Neo", "Morpheus"]
RETURN DISTINCT (p1) AS person, count(r_pfq) AS friend_score, collect(fq.name) AS friends
ORDER BY friend_score DESC
LIMIT 10
UNION
MATCH (p:Crew)-->(f:Crew)<-[r_fqf]-(fq:Crew)
WHERE fq.name IN ["Neo", "Morpheus"]
WITH f, count(r_fqf) AS weight, p
WITH f, sum(weight) AS friend_score, p
RETURN DISTINCT (p) AS person, friend_score, collect(DISTINCT (f).name) AS friends
ORDER BY friend_score DESC
LIMIT 10

Resources