After searching for all nodes connected between nodes, how do I output only some of the nodes connected between them?

Hello.
I ran the following cypher.

(:Account)-[:Date]->(:Date)-[:ACTED]->(:Log)-[:ACTED*]-(:Log)-[:DETECTED]->(:Rule)

To explain the cypher above,

  1. (Account) Only one node exists.
  2. There are several (Date) nodes that connect to the (Account) node (approximately 10).
  3. There are several (approximately 50 or more) (Log) nodes leading from the (Date) node to the first [ACTED] relationship.
  4. The above [3] (Log) nodes are again [:ACTED] for each (Log) node, so from now on, they are connected in a single line to the (:Log) node.
    In this case, the number of (Log) nodes connected by the [ACTED] relationship is 10 to 1000 or more per (Log).
  5. Many (:Log) nodes connected in a single line will one day be connected to the (:Rule) node connected in a [:DETECTED] relationship.

Assuming that you find a large number of (:Log) nodes in the [5] and graph the flow, it can be massive in shape or overload the server.

And here's the question.
Q-1.
How do I output only some of the many (:Logs) and keep the relationship with the rest of the nodes intact?

Q-2.
Many (:Log) nodes that are connected in [5] single lines have a property value called eventName.
The format is:
eventName: 'A'

Which cypher outputs only some of the many (:Log) logs, gets the corresponding number of (


:Log) nodes, gets the number of each eventName, and creates a new node with each information?

Examples include.
Total_Nodes: 1024
A: 5
B: 38
C: 124
...

The picture below is the result of me running the following cypher.

MATCH (account:Account:Iam)-[:DATE]->(date:Date)-[:ACTED]->(log:Log)

WHERE account.name = 'ar_hk'

OPTIONAL MATCH (log2:Log)-[:DETECTED]->(rule:Rule)

WHERE log2.userIdentity_userName = 'ar_hk'

WITH account, date, log, COLLECT(log2) AS logs, COLLECT(rule) AS rules

RETURN account, date, log, logs, rules

The yellow node is the Account node.
The blue node is the Date node.
The pink node is the Log node.
The red node is the Rule node.

In the graph in the picture, there are many connected Log nodes, which are pink nodes, each of which is the first and last of each flow.

If I am understanding correctly, here are my answers:

  1. You could replace the variable length path from the initial Log node to the terminal Rule node with a single virtual relationship for visualization. You will need to deal with the case when the optional match does not return a value for Rule, as the 'create virtual relationship' method does not accept null nodes. One approach is to return a constant for this case, as a constant will not affect your virtualization. The following is an example using a CASE statement to conditionally call the apoc method:
match(n:X{name:'A'}) 
optional match(n)--(p)
return case when p is null then 1 else apoc.create.vRelationship(n,'VREL',{},p) end, n, p

In the following example, I had only one node that had a relationship. As shown in the second screeenshot a virtual relationship (VREL) was created for this case.

Note: returning null instead of a constant 1 works as well.

  1. You can use the following approach if you collect the list of Log nodes with the name property that you want to tally. The result is a map with the different values of name as the map's keys and their corresponding value equal to the tally.

Test data:

match(n:X)
with collect(n) as nodes
with apoc.map.groupByMulti(nodes, "name") as map
return apoc.map.fromLists(keys(map),[i in keys(map)|size(map[i])])

Question:

In your query the option match is anchored to log2, which is not related to the initial match statement. I assume there is an indirect relationship between the commonality of the name attribute with value 'ar_hk'. If this is true, can you rewrite the query as the following:

MATCH (account:Account:Iam)-[:DATE]->(date:Date)-[:ACTED]->(log:Log)
WHERE account.name = 'ar_hk'
OPTIONAL MATCH (log)-[:DETECTED]->(rule:Rule)
WITH account, date, log, COLLECT(rule) AS rules
RETURN account, date, log, rules

If so, you can also eliminate the optional match using the new collect subquery:

MATCH (account:Account:Iam)-[:DATE]->(date:Date)-[:ACTED]->(log:Log)
WHERE account.name = 'ar_hk'
RETURN account, date, log, 
COLLECT{
    MATCH (log)-[:DETECTED]->(rule:Rule)
    RETURN rule
} AS rules