Neo4j 'match' within 'unwind' operation - neo4j

I have a Neo4j query where I am trying to get all distinct ids and then, for each id, return all nodes that match that id. Here's what my query looks like:
match (x:Log) with collect(distinct x.id) as ids
unwind ids as i
match (y:Log {id:i}) return y;
I was hoping that the results of this query would be grouped by id aka have multiple nodes per row, where each row holds all nodes that share an id. Instead it is returning only one node per row, and there are multiple rows of the same id. How do I get the results to be grouped by id?
Example: Let's say there are five nodes of label Log. Two of the Log nodes have id='abc' and three of them have id='123'. Right now, my query is returning five rows that each contain one node, but I would like it to return two rows: one row that contains all the Log nodes of id='123', and another row that contains all the Log nodes of id='abc'.

This will return a distinct id per row, along with the nodes having that id:
MATCH (x:Log)
RETURN x.id AS id, COLLECT(x) as nodes;

Related

Duplicate relationship in Neo4j

Why does this create two relationships instead of one?
MATCH (a:Person{name:'Barack'}), (b:Person{name:'Raback'})
CREATE (a)-[r:SHAKES_HANDS_WITH{id:toString(rand())}]->(b)
RETURN r
(Random number "id" is just added for demo purposes.)
You probably have 2 Person nodes with the same name (either 'Barack' or 'Raback').
Assuming that the other name has only a single node, the MATCH clause will produce 2 rows -- which will cause the the CREATE clause to be executed twice.
To verify if this is your scenario, this query will show you how many nodes have each name:
MATCH (a:Person)
WHERE a.name IN ['Barack', 'Raback']
RETURN a.name, COUNT(a) as nodeCount

How to return single node with Multiple match for different labels in neo4j?

I am using neo4j 3.2.x. What I am try to do is write a query that will update relation between two nodes (User and Gender) and return single User node with InterestedInGender property pulled from relation as array. There is a problem with the below query as right now it returns multiple records with single value for interestedInGender. Relations are created properly but when returning data it is returning multiple records. I just want to return User node. Is there any way we can fix this query to just return single user node.
MATCH (u:User {_id:"1234"})
MATCH (ig:Gender) WHERE ig.value IN ["male", "female"]
WITH u, ig
OPTIONAL MATCH (u)-[igr:INTERESTED_IN_GENDER]->()
DELETE igr
with u, ig
MERGE (u)-[:INTERESTED_IN_GENDER]->(ig)
RETURN u{
._id,
interestedInGender: [(u)-[:INTERESTED_IN_GENDER]->(ig:Gender) | ig.value]
}
The reason you're getting multiple records (rows) is because your ig match to gender matches to two :Gender nodes...two rows where both rows have the same u node, but different ig nodes. That cardinality remains throughout the rest of your query, and so you get two rows back.
You need to shrink the cardinality of u back down to 1 after you MERGE the relationship, so add this after your MERGE but before your RETURN:
WITH distinct u

Duplicate object in a list when I try to map all related entities

According to this post I tried to map all related entities in a list.
I used the same query into the post with a condition to return a list of User but it returns duplicate object
MATCH (user:User) WHERE <complex conditions>
WITH user, calculatedValue
MATCH p=(user)-[r*0..1]-() RETURN user, calculatedValue, nodes(p), rels(p)
Is it a bug? I'm using SDN 4.2.4.RELEASE with neo4j 3.2.1
Not a bug.
Keep in mind a MATCH in Neo4j will find all occurrences of a given pattern. Let's look at your last MATCH:
MATCH p=(user)-[r*0..1]-()
Because you have a variable match of *0..1, this will always return at least one row with just the user itself (with rels(p) empty and nodes(p) containing only the user), and then you'll get a row for every connected node (user will always be present on that row, and in the nodes(p) collection, along with the other connected node).
In the end, when you have a single user node and n directly connected nodes, you will get n + 1 rows. You can run the query in the Neo4j browser, looking at the table results, to confirm.
A better match might be something like:
...
OPTIONAL MATCH (user)-[r]-(b)
RETURN user, calculatedValue, collect(r) as rels, collect(b) as connectedNodes
Because we aggregate on all relationships and connected nodes (rather than just the relationships and nodes for each path), you'll get a single row result per user node.

Trying a single Neo4j Cypher query for my graph

I have "users" who owns "items", users are also friends w/ each other. I am trying to construct a cypher query to return all items I own PLUS those my friends own in a single query. I can do them individually but can't figure out how to do it in a single query.
RELATIONSHIPS:
(u:user)-[:OWNS]-(i:items)
(u:user)-[:FRIEND]-(f:user)
Let's say I have just two users in my DB and 100 items. Out of 100, the first person owns (1-5) 5 items and the 2nd person owns another 5 items(6-10). These two users are also friends.
I get 5 items if I do:
MATCH (uer1)-[:OWNS]->(i:items) return i
I get another 5 items if I do:
MATCH (uer1)-[:FRIEND]->(f)-[:OWNS]->(i:items) return i
But I need to combine them both for a given user(user1) so I can return all 10 items in a single shot. How to do that?
You have two (or more options)
Union
MATCH (user:User {name:"Raja"})-[:OWNS]->(i:Item) return i
UNION
MATCH (user:User {name:"Raja"})-[:FRIEND]->(f)-[:OWNS]->(i:Item) return i
Variable length paths
MATCH (user:User {name:"Raja"})-[:FRIEND*0..1]->(f)-[:OWNS]->(i:Item) return i
in this case we look at friends of the distance 0 (the user itself) to one (first degree friends)
The first option might be faster
The second is more versatile.

neo4j match statment returns more nodes then wanted

I have in my DB a user node that is connected to a userDevice node. On the relationship between them, there is a property called pushId.
I'm trying to get a list of the pushIds and the user devices ids of a specific users.
match (user:User)-[r:WITH_DEVICE]->(device:UserDevice)
where user.id="222" or user.id="243243"
RETURN r.pushId,device.id
instead of 2 rows it duplicate one row twice and return 3 rows.
Use DISTINCT keyword
match (user:User)-[r:WITH_DEVICE]->(device:UserDevice)
where user.id="222" or user.id="243243"
RETURN DISTINCT r.pushId,device.id
http://neo4j.com/docs/stable/query-return.html#return-unique-results

Resources