Skip to content

Commit 83f6053

Browse files
committed
test data and queris
1 parent 761bc0c commit 83f6053

File tree

3 files changed

+407
-0
lines changed

3 files changed

+407
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Step 1: Find all nodes containing the specified property
2+
// Use a subquery to handle both MATCH conditions
3+
CALL {
4+
WITH $propertyNames AS propertyNames
5+
UNWIND propertyNames AS propertyName
6+
// Match nodes that directly contain the specified property
7+
MATCH (simple_node)
8+
WHERE simple_node[propertyName] IS NOT NULL
9+
RETURN DISTINCT simple_node AS resultNode
10+
UNION
11+
WITH $propertyNames AS propertyNames
12+
UNWIND propertyNames AS propertyName
13+
// Match nodes that are related via a specific relationship property
14+
MATCH (nested_node)-[r:PARENT_OF {attribute_name: propertyName}]->(:NESTED_ATTRIBUTE)
15+
WHERE r.type IN ["list", "dict"]
16+
RETURN DISTINCT nested_node AS resultNode
17+
}
18+
19+
// Step 2: Use APOC to find the path from each node to the root, excluding 'NESTED_ATTRIBUTE' nodes
20+
CALL apoc.path.subgraphNodes(resultNode, {
21+
relationshipFilter: 'PARENT_OF<',
22+
labelFilter: '-NESTED_ATTRIBUTE',
23+
maxLevel: -1
24+
}) YIELD node AS pathNode
25+
26+
// Step 3: Collect the nodes along the path and construct the full name
27+
WITH resultNode,
28+
COLLECT(pathNode) AS pathNodes
29+
WITH resultNode,
30+
REDUCE(fullPath = '', n IN pathNodes |
31+
CASE
32+
WHEN fullPath = '' THEN n.node_name
33+
ELSE n.node_name + '/' + fullPath
34+
END) AS fullName
35+
// Step 4: Find nested children with label "NESTED_ATTRIBUTE" and their relationships
36+
OPTIONAL MATCH (resultNode)-[r:PARENT_OF]->(nestedChild:NESTED_ATTRIBUTE)
37+
OPTIONAL MATCH (nestedChild)-[nestedRel:PARENT_OF*]->(child:NESTED_ATTRIBUTE)
38+
39+
// Step 5: Return the full path, resultNode, nested children, and relationships
40+
RETURN DISTINCT
41+
fullName,
42+
resultNode,
43+
COLLECT(DISTINCT nestedChild) AS nestedChildren,
44+
COLLECT(DISTINCT r) + COLLECT(DISTINCT nestedRel) AS relationships
45+
46+
-----------------
47+
48+
-----------------
49+
// Get node based on topics. Does not work for # and + entries. need atleast one
50+
WITH $topics AS inputPaths
51+
UNWIND inputPaths AS inputPath
52+
WITH split(inputPath, '/') AS nodeNames, inputPath
53+
54+
// Step 1: Match the root node based on the first part of the path
55+
MATCH (root {node_name: nodeNames[0]})
56+
57+
// Step 2: Expand paths from the root node
58+
CALL apoc.path.expand(
59+
root,
60+
'PARENT_OF>',
61+
'', // No label filter
62+
0, // Min depth 0 to include the root node
63+
-1 // Max depth is unlimited to cover all possible depths
64+
) YIELD path AS fullPath
65+
66+
// Step 3: Filter paths according to the inputPath with wildcards
67+
WITH fullPath, nodeNames, nodes(fullPath) AS nodesPath
68+
WITH fullPath, nodeNames, nodesPath, last(nodes(fullPath)) AS lastNode
69+
WHERE
70+
size(nodesPath) >= size(nodeNames) AND
71+
all(i IN range(0, size(nodeNames) - 1) WHERE
72+
(nodeNames[i] = '+' AND size(nodesPath) > i) OR
73+
(nodeNames[i] = '#' AND size(nodesPath) > i) OR
74+
(nodeNames[i] = nodesPath[i].node_name)
75+
) AND
76+
(size(nodeNames) = size(nodesPath) OR nodeNames[-1] = '#' OR nodeNames[-1] = lastNode.node_name)
77+
78+
// Step 4: Construct the MQTT topic path from the matched path
79+
WITH fullPath, lastNode, reduce(fullPathStr = '', n IN nodesPath |
80+
CASE
81+
WHEN fullPathStr = '' THEN n.node_name
82+
ELSE fullPathStr + '/' + n.node_name
83+
END) AS mqttTopic
84+
85+
// Step 5: Exclude paths containing 'NESTED_ATTRIBUTE' nodes in the path
86+
WHERE NOT any(n IN nodesPath WHERE 'NESTED_ATTRIBUTE' IN labels(n))
87+
88+
// Step 6: Match directly connected nested children of the last node that have the label 'NESTED_ATTRIBUTE'
89+
OPTIONAL MATCH (lastNode)-[r:PARENT_OF]->(nestedChild:NESTED_ATTRIBUTE)
90+
91+
// Step 7: Match any children of the nestedChild if they have the label "NESTED_ATTRIBUTE"
92+
OPTIONAL MATCH (nestedChild)-[nestedRel:PARENT_OF*]->(child:NESTED_ATTRIBUTE)
93+
94+
// Step 8: Collect results
95+
WITH DISTINCT mqttTopic, lastNode,
96+
COLLECT(DISTINCT nestedChild) AS nestedChildren,
97+
COLLECT(DISTINCT r) + COLLECT(DISTINCT nestedRel) AS relationships
98+
99+
// Step 9: Return the MQTT topic path, the last node, nested children, and relationships
100+
RETURN
101+
mqttTopic,
102+
lastNode as node,
103+
nestedChildren,
104+
relationships

0 commit comments

Comments
 (0)