Neo4j: Link Different Nodes to the one node

2019-08-26 07:52发布

问题:

Let's say you have the following 4 nodes:

Set 1: (act: "Event Log", timestamp: 3461000) (act: "Uptime Report", timestamp: 3461000)

Set 2: (act: "Event Log", timestamp: 149100) (act: "Uptime Report", timestamp: 149100)

I am trying to figure out how to map each set of nodes to one node. I tried the following Cypher but all 4 nodes are mapping to only one node, (a) instead of creating two (a) nodes and mapping the 2 sets respectively. Is it necessary to have a condition that looks for the matching timestamp of the (act) nodes? Then, if the timestamp do match then link those nodes to (a)? Any help would be greatly appreciated.

MATCH (seconds)<-[:AT_TIME]-(act)--(obj) 
WHERE reqObj.filename IN ["6013", "6005"]
MERGE (a:Abs{name: 'SigEvent'})
CREATE (reqAct)-[:LINK]->(a)

回答1:

So if I understand correctly, you want an :Abs node for each distinct timestamp in the act nodes. To do this, we'll need to aggregate act nodes by timestamp (so you'll get only a single row per distinct timestamp), then CREATE the :Abs node, then do a FOREACH to create the relationships to the new node.

MATCH (act)--(obj) 
WHERE obj.filename IN ["6013", "6005"]
WITH act.timestamp as timestamp, collect(DISTINCT act) as acts
CREATE (a:Abs{name: 'SigEvent'}) // created per row, so per distinct timestamp
FOREACH (act in acts | CREATE (act)-[:LINK]->(a))

I removed the part of the match pattern to seconds as it didn't look like you were using that.

There is a major problem in this query though. This match can't use any index lookup since you aren't using labels in the match pattern, so this is doing an all nodes scan which will result in terrible performance as the graph grows. You at least need a label on one of these. It looks like you intend to do an index lookup on obj.filename, so add the appropriate label to obj in your MATCH pattern so your index (if you've created one) can be used.