Skip to content

Commit fa5d1ef

Browse files
committed
Remove extra collect from connections without projection
1 parent fb46e96 commit fa5d1ef

File tree

15 files changed

+53
-51
lines changed

15 files changed

+53
-51
lines changed

packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ export class ConnectionReadOperation extends Operation {
135135
nodeAndRelationshipMap.set("relationship", nestedContext.relationship);
136136
}
137137

138-
const withClause = new Cypher.With([Cypher.collect(nodeAndRelationshipMap), edgesVar], ...extraColumns);
138+
const withClause = new Cypher.With();
139+
if (this.shouldProjectEdges()) {
140+
withClause.addColumns([Cypher.collect(nodeAndRelationshipMap), edgesVar]);
141+
}
142+
withClause.addColumns(...extraColumns);
139143

140144
if (this.hasTotalCount) {
141145
withClause.addColumns([Cypher.count(nestedContext.target), totalCount]);
@@ -203,13 +207,26 @@ export class ConnectionReadOperation extends Operation {
203207
};
204208
}
205209

206-
const hasProjectionFields = this.hasEdgesProjection();
210+
const hasProjectionFields = this.shouldProjectEdges();
207211
let unwindAndProjectionSubquery: Cypher.Call | undefined;
208212
if (hasProjectionFields) {
209-
unwindAndProjectionSubquery = this.createUnwindAndProjectionSubquery(
210-
nestedContext,
211-
edgesVar,
212-
edgesProjectionVar
213+
const edgeVar = new Cypher.NamedVariable("edge");
214+
const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext);
215+
216+
const unwindClause = this.getUnwindClause(nestedContext, edgeVar, edgesVar);
217+
218+
const edgeProjectionMap = this.createProjectionMapForEdge(nestedContext);
219+
const paginationWith = this.generateSortAndPaginationClause(nestedContext);
220+
221+
unwindAndProjectionSubquery = new Cypher.Call(
222+
Cypher.utils.concat(
223+
unwindClause,
224+
...prePaginationSubqueries,
225+
paginationWith,
226+
...postPaginationSubqueries,
227+
new Cypher.Return([Cypher.collect(edgeProjectionMap), edgesProjectionVar])
228+
),
229+
[edgesVar]
213230
);
214231
}
215232

@@ -269,7 +286,7 @@ export class ConnectionReadOperation extends Operation {
269286
}
270287

271288
/** Defines if the query should project edges */
272-
protected hasEdgesProjection(): boolean {
289+
protected shouldProjectEdges(): boolean {
273290
const hasPagination = Boolean(this.pagination);
274291
const hasFields = this.nodeFields.length + this.edgeFields.length > 0;
275292
return hasPagination || hasFields;

packages/graphql/src/translate/queryAST/ast/operations/FulltextOperation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ export class FulltextOperation extends ConnectionReadOperation {
6262
return filterTruthy([...super.getChildren(), this.scoreField]);
6363
}
6464

65-
protected hasEdgesProjection(): boolean {
66-
return super.hasEdgesProjection() || Boolean(this.scoreField);
65+
protected shouldProjectEdges(): boolean {
66+
return super.shouldProjectEdges() || Boolean(this.scoreField);
6767
}
6868

6969
protected createProjectionMapForEdge(context: QueryASTContext<Cypher.Node>): Cypher.Map {

packages/graphql/tests/performance/graphql/connections.graphql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,9 @@ query NestedConnection {
2828
}
2929
}
3030
}
31+
32+
query totalCount {
33+
moviesConnection {
34+
totalCount
35+
}
36+
}

packages/graphql/tests/tck/connections/alias.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ describe("Connections Alias", () => {
6464
MATCH (this:Movie)
6565
CALL (this) {
6666
MATCH (this)<-[this0:ACTED_IN]-(this1:Actor)
67-
WITH collect({ node: this1, relationship: this0 }) AS edges
68-
WITH edges, size(edges) AS totalCount
67+
WITH count(this1) AS totalCount
6968
RETURN { totalCount: totalCount } AS var2
7069
}
7170
RETURN this { actors: var2 } AS this"

packages/graphql/tests/tck/connections/projections/projections.test.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ describe("Relay Cursor Connection projections", () => {
6464
"CYPHER 5
6565
MATCH (this0:Movie)
6666
WHERE this0.title = $param0
67-
WITH collect({ node: this0 }) AS edges
68-
WITH edges, size(edges) AS totalCount
67+
WITH count(this0) AS totalCount
6968
RETURN { totalCount: totalCount } AS this"
7069
`);
7170

@@ -91,8 +90,7 @@ describe("Relay Cursor Connection projections", () => {
9190
"CYPHER 5
9291
MATCH (this0:Movie)
9392
WHERE this0.title = $param0
94-
WITH collect({ node: this0 }) AS edges
95-
WITH edges, size(edges) AS totalCount
93+
WITH count(this0) AS totalCount
9694
RETURN { totalCount: totalCount } AS this"
9795
`);
9896

@@ -123,8 +121,7 @@ describe("Relay Cursor Connection projections", () => {
123121
WHERE this.title = $param0
124122
CALL (this) {
125123
MATCH (this)<-[this0:ACTED_IN]-(this1:Actor)
126-
WITH collect({ node: this1, relationship: this0 }) AS edges
127-
WITH edges, size(edges) AS totalCount
124+
WITH count(this1) AS totalCount
128125
RETURN { totalCount: totalCount } AS var2
129126
}
130127
RETURN this { .title, actorsConnection: var2 } AS this"
@@ -162,8 +159,7 @@ describe("Relay Cursor Connection projections", () => {
162159
WHERE this.title = $param0
163160
CALL (this) {
164161
MATCH (this)<-[this0:ACTED_IN]-(this1:Actor)
165-
WITH collect({ node: this1, relationship: this0 }) AS edges
166-
WITH edges, size(edges) AS totalCount
162+
WITH count(this1) AS totalCount
167163
RETURN { totalCount: totalCount } AS var2
168164
}
169165
RETURN this { .title, actorsConnection: var2 } AS this"
@@ -196,8 +192,7 @@ describe("Relay Cursor Connection projections", () => {
196192
WHERE this.title = $param0
197193
CALL (this) {
198194
MATCH (this)<-[this0:ACTED_IN]-(this1:Actor)
199-
WITH collect({ node: this1, relationship: this0 }) AS edges
200-
WITH edges, size(edges) AS totalCount
195+
WITH collect({ node: this1, relationship: this0 }) AS edges, count(this1) AS totalCount
201196
CALL (edges) {
202197
UNWIND edges AS edge
203198
WITH edge.node AS this1, edge.relationship AS this0
@@ -345,8 +340,7 @@ describe("Relay Cursor Connection projections", () => {
345340
WHERE this.title = $param0
346341
CALL (this) {
347342
MATCH (this)<-[this0:ACTED_IN]-(this1:Actor)
348-
WITH collect({ node: this1, relationship: this0 }) AS edges
349-
WITH edges, size(edges) AS totalCount
343+
WITH collect({ node: this1, relationship: this0 }) AS edges, count(this1) AS totalCount
350344
CALL (edges) {
351345
UNWIND edges AS edge
352346
WITH edge.node AS this1, edge.relationship AS this0
@@ -389,8 +383,7 @@ describe("Relay Cursor Connection projections", () => {
389383
WHERE this.title = $param0
390384
CALL (this) {
391385
MATCH (this)<-[this0:ACTED_IN]-(this1:Actor)
392-
WITH collect({ node: this1, relationship: this0 }) AS edges
393-
WITH edges, size(edges) AS totalCount
386+
WITH collect({ node: this1, relationship: this0 }) AS edges, count(this1) AS totalCount
394387
CALL (edges) {
395388
UNWIND edges AS edge
396389
WITH edge.node AS this1, edge.relationship AS this0

packages/graphql/tests/tck/deprecated/cypher-sort-deprecated.test.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,7 @@ describe("Cypher sort deprecated", () => {
450450
expect(formatCypher(result.cypher)).toMatchInlineSnapshot(`
451451
"CYPHER 5
452452
MATCH (this0:Movie)
453-
WITH collect({ node: this0 }) AS edges
454-
WITH edges, size(edges) AS totalCount
453+
WITH collect({ node: this0 }) AS edges, count(this0) AS totalCount
455454
CALL (edges) {
456455
UNWIND edges AS edge
457456
WITH edge.node AS this0
@@ -535,8 +534,7 @@ describe("Cypher sort deprecated", () => {
535534
MATCH (this:Actor)
536535
CALL (this) {
537536
MATCH (this)-[this0:ACTED_IN]->(this1:Movie)
538-
WITH collect({ node: this1, relationship: this0 }) AS edges
539-
WITH edges, size(edges) AS totalCount
537+
WITH collect({ node: this1, relationship: this0 }) AS edges, count(this1) AS totalCount
540538
CALL (edges) {
541539
UNWIND edges AS edge
542540
WITH edge.node AS this1, edge.relationship AS this0

packages/graphql/tests/tck/deprecated/generic-filtering/cypher-filtering-one-to-one-relationship-deprecated.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,8 +1496,7 @@ describe("cypher directive filtering - One To One Relationship - deprecated", ()
14961496
WHERE (this.title ENDS WITH $param0 AND this1.name = $param1)
14971497
CALL (this) {
14981498
MATCH (this)<-[this2:ACTED_IN]-(this3:Person)
1499-
WITH collect({ node: this3, relationship: this2 }) AS edges
1500-
WITH edges, size(edges) AS totalCount
1499+
WITH collect({ node: this3, relationship: this2 }) AS edges, count(this3) AS totalCount
15011500
CALL (edges) {
15021501
UNWIND edges AS edge
15031502
WITH edge.node AS this3, edge.relationship AS this2

packages/graphql/tests/tck/directives/cypher/filtering/cypher-filtering-one-to-one-relationship.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,8 +1508,7 @@ describe("cypher directive filtering - One To One Relationship", () => {
15081508
WHERE (this.title ENDS WITH $param0 AND this1.name = $param1)
15091509
CALL (this) {
15101510
MATCH (this)<-[this2:ACTED_IN]-(this3:Person)
1511-
WITH collect({ node: this3, relationship: this2 }) AS edges
1512-
WITH edges, size(edges) AS totalCount
1511+
WITH collect({ node: this3, relationship: this2 }) AS edges, count(this3) AS totalCount
15131512
CALL (edges) {
15141513
UNWIND edges AS edge
15151514
WITH edge.node AS this3, edge.relationship AS this2

packages/graphql/tests/tck/issues/2022.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => {
9090
expect(formatCypher(result.cypher)).toMatchInlineSnapshot(`
9191
"CYPHER 5
9292
MATCH (this0:ArtPiece)
93-
WITH collect({ node: this0 }) AS edges
94-
WITH edges, size(edges) AS totalCount
93+
WITH collect({ node: this0 }) AS edges, count(this0) AS totalCount
9594
CALL (edges) {
9695
UNWIND edges AS edge
9796
WITH edge.node AS this0

packages/graphql/tests/tck/issues/2437.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ describe("https://github.com/neo4j/graphql/issues/2437", () => {
8888
CALL (this) {
8989
MATCH (this)-[this0:IS_VALUATION_AGENT]->(this1:Valuation)
9090
WHERE ($isAuthenticated = true AND this1.archivedAt IS NULL)
91-
WITH collect({ node: this1, relationship: this0 }) AS edges
92-
WITH edges, size(edges) AS totalCount
91+
WITH collect({ node: this1, relationship: this0 }) AS edges, count(this1) AS totalCount
9392
CALL (edges) {
9493
UNWIND edges AS edge
9594
WITH edge.node AS this1, edge.relationship AS this0

0 commit comments

Comments
 (0)