Skip to content

Commit 8d4fa33

Browse files
authored
[NOID] Return a node even if no relationships exist (#4168)
1 parent 8a5d4f8 commit 8d4fa33

File tree

2 files changed

+73
-2
lines changed

2 files changed

+73
-2
lines changed

core/src/main/java/apoc/convert/Json.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ public Stream<MapResult> toTree(
234234
@Procedure("apoc.paths.toJsonTree")
235235
@Description(
236236
"apoc.paths.toJsonTree([paths],[lowerCaseRels=true], [config]) creates a stream of nested documents representing the graph as a tree by traversing outgoing relationships")
237-
// todo optinally provide root node
238237
public Stream<MapResult> pathsToTree(
239238
@Name("paths") List<Path> paths,
240239
@Name(value = "lowerCaseRels", defaultValue = "true") boolean lowerCaseRels,
@@ -254,6 +253,16 @@ public Stream<MapResult> pathsToTree(
254253
allPaths.forEach(path -> {
255254
// This api will always return relationships in an outgoing fashion ()-[r]->()
256255
var pathRelationships = path.relationships();
256+
// If no relationships exist in the path, then add the node by itself
257+
if (!pathRelationships.iterator().hasNext()) {
258+
Node currentNode = path.startNode();
259+
Long currentNodeId = currentNode.getId();
260+
261+
if (!visitedInOtherPaths.contains(currentNodeId)) {
262+
nodesToKeepInResult.add(currentNodeId);
263+
}
264+
tree.computeIfAbsent(currentNode.getId(), (id) -> toMap(currentNode, nodes));
265+
}
257266
pathRelationships.iterator().forEachRemaining((currentRel) -> {
258267
Node currentNode = currentRel.getStartNode();
259268
Long currentNodeId = currentNode.getId();

core/src/test/java/apoc/convert/PathsToJsonTreeTest.java

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void clear() {
5656
}
5757

5858
@Test
59-
public void testToTreeSimplePath() throws Exception {
59+
public void testToTreeSimplePath() {
6060
/* r:R
6161
a:A --------> b:B
6262
*/
@@ -90,6 +90,68 @@ public void testToTreeSimplePath() throws Exception {
9090
}
9191
}
9292

93+
@Test
94+
public void testSingleNode() {
95+
// a:A
96+
db.executeTransactionally("CREATE (a: A {nodeName: 'a'})");
97+
98+
var query = "MATCH path = (n)\n"
99+
+ "WITH COLLECT(path) AS paths\n"
100+
+ "CALL apoc.paths.toJsonTree(paths, true, {sortPaths: false}) YIELD value AS tree\n"
101+
+ "RETURN tree";
102+
103+
try (Transaction tx = db.beginTx()) {
104+
Result result = tx.execute(query);
105+
var rows = result.stream().collect(Collectors.toList());
106+
var expectedRow = "{" + " \"tree\":{"
107+
+ " \"nodeName\":\"a\","
108+
+ " \"_type\":\"A\","
109+
+ " \"_id\":0"
110+
+ " }"
111+
+ "}";
112+
assertEquals(rows.size(), 1);
113+
assertEquals(parseJson(expectedRow), rows.get(0));
114+
}
115+
}
116+
117+
@Test
118+
public void testSingleDisjointNodes() {
119+
// a:A
120+
db.executeTransactionally("CREATE (a: A {nodeName: 'a'}), (b: B {nodeName: 'b'}), (c: C {nodeName: 'c'})");
121+
122+
var query = "MATCH path = (n)\n"
123+
+ "WITH COLLECT(path) AS paths\n"
124+
+ "CALL apoc.paths.toJsonTree(paths, true, {sortPaths: false}) YIELD value AS tree\n"
125+
+ "RETURN tree";
126+
127+
try (Transaction tx = db.beginTx()) {
128+
Result result = tx.execute(query);
129+
var rows = result.stream().collect(Collectors.toList());
130+
var expectedRowA = "{" + " \"tree\":{"
131+
+ " \"nodeName\":\"a\","
132+
+ " \"_type\":\"A\","
133+
+ " \"_id\":0"
134+
+ " }"
135+
+ "}";
136+
var expectedRowB = "{" + " \"tree\":{"
137+
+ " \"nodeName\":\"b\","
138+
+ " \"_type\":\"B\","
139+
+ " \"_id\":1"
140+
+ " }"
141+
+ "}";
142+
var expectedRowC = "{" + " \"tree\":{"
143+
+ " \"nodeName\":\"c\","
144+
+ " \"_type\":\"C\","
145+
+ " \"_id\":2"
146+
+ " }"
147+
+ "}";
148+
assertEquals(rows.size(), 3);
149+
assertEquals(parseJson(expectedRowA), rows.get(0));
150+
assertEquals(parseJson(expectedRowB), rows.get(1));
151+
assertEquals(parseJson(expectedRowC), rows.get(2));
152+
}
153+
}
154+
93155
@Test
94156
public void testToTreeSimpleReversePath() {
95157
/* r:R

0 commit comments

Comments
 (0)