Skip to content

Commit 1deb6df

Browse files
nodecount rmv/replace with nodePropertiesWritten
1 parent 13ad610 commit 1deb6df

File tree

7 files changed

+29
-50
lines changed

7 files changed

+29
-50
lines changed

doc/modules/ROOT/pages/algorithms/clique-counting.adoc

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ include::partial$/algorithms/shared/algorithm-traits.adoc[]
1212

1313
[[algorithms-clique-counting-intro]]
1414
== Introduction
15-
A clique is a subset of nodes where all nodes are connected to each other, sometimes called a complete subgraph. The clique counting algorithm counts the number of cliques of various sizes in the graph. In GDS this is done efficiently, without realizing every clique, through a Succinct Clique Tree-structure, see https://dl.acm.org/doi/pdf/10.1145/3336191.3371839[The Power of Pivoting for Exact Clique Counting]
15+
A clique is a subset of nodes where all nodes are connected to each other, sometimes called a complete subgraph. The clique counting algorithm counts the number of cliques of various sizes in the graph. In GDS this is done efficiently, without realizing every clique, through a Succinct Clique Tree-structure, see https://dl.acm.org/doi/pdf/10.1145/3336191.3371839[The Power of Pivoting for Exact Clique Counting].
1616

1717
Counting the number of cliques in the graph, can give an understanding for the topology and clustering of the graph in its entirety as well as for individual nodes. The algorithm counts only cliques of size 3 or larger, since cliques of sizes 1 and 2 are trivial (nodes and relationships, respectively). If you are only interested in triangles (cliques of size 3), the xref:algorithms/triangle-count.adoc[Triangle Count] is a better choice.
1818

@@ -40,9 +40,8 @@ CALL gds.cliqueCounting.stream(
4040
)
4141
YIELD
4242
nodeId: Integer,
43-
perNodeCount: List
43+
counts: List
4444
----
45-
//todo: check above
4645

4746
include::partial$/algorithms/common-configuration/common-parameters.adoc[]
4847

@@ -56,9 +55,9 @@ include::partial$/algorithms/common-configuration/common-stream-stats-configurat
5655
.Results
5756
[opts="header",cols="1,1,6"]
5857
|===
59-
| Name | Type | Description
60-
| nodeId | Integer | Node ID.
61-
| perNodeCount | List of Integer | Number of cliques of size ≥ 3 that this node is part of.
58+
| Name | Type | Description
59+
| nodeId | Integer | Node ID.
60+
| counts | List of Integer | Number of cliques of size ≥ 3 that this node is part of.
6261
|===
6362
======
6463
@@ -76,10 +75,8 @@ YIELD
7675
globalCount: List,
7776
preProcessingMillis: Integer,
7877
computeMillis: Integer,
79-
postProcessingMillis: Integer,
8078
configuration: Map
8179
----
82-
//todo: Test this
8380
include::partial$/algorithms/common-configuration/common-parameters.adoc[]
8481

8582
.Configuration
@@ -96,7 +93,6 @@ include::partial$/algorithms/common-configuration/common-stream-stats-configurat
9693
| globalCount | List of Integer | Number of cliques of sizes ≥ 3 in the graph.
9794
| preProcessingMillis | Integer | Milliseconds for preprocessing the graph.
9895
| computeMillis | Integer | Milliseconds for running the algorithm.
99-
| postProcessingMillis | Integer | Milliseconds for computing the global metrics.
10096
| configuration | Map | The configuration used for running the algorithm.
10197
|===
10298
======
@@ -108,7 +104,7 @@ include::partial$/algorithms/common-configuration/common-stream-stats-configurat
108104
.Run Clique Counting in mutate mode on a named graph:
109105
[source, cypher, role=noplay]
110106
----
111-
CALL gds.cliqueCount.mutate(
107+
CALL gds.cliqueCounting.mutate(
112108
graphName: String,
113109
configuration: Map
114110
)
@@ -117,11 +113,9 @@ YIELD
117113
nodePropertiesWritten: Integer,
118114
preProcessingMillis: Integer,
119115
computeMillis: Integer,
120-
postProcessingMillis: Integer,
121116
mutateMillis: Integer,
122117
configuration: Map
123118
----
124-
//todo: Test this
125119
include::partial$/algorithms/common-configuration/common-parameters.adoc[]
126120

127121
.Configuration
@@ -139,7 +133,6 @@ include::partial$/algorithms/common-configuration/common-mutate-configuration-en
139133
| nodePropertiesWritten | Integer | Number of properties added to the projected graph.
140134
| preProcessingMillis | Integer | Milliseconds for preprocessing the graph.
141135
| computeMillis | Integer | Milliseconds for running the algorithm.
142-
| postProcessingMillis | Integer | Milliseconds for computing the global metrics.
143136
| mutateMillis | Integer | Milliseconds for adding properties to the projected graph.
144137
| configuration | Map | The configuration used for running the algorithm.
145138
|===
@@ -160,11 +153,9 @@ YIELD
160153
nodePropertiesWritten: Integer,
161154
preProcessingMillis: Integer,
162155
computeMillis: Integer,
163-
postProcessingMillis: Integer,
164156
writeMillis: Integer,
165157
configuration: Map
166158
----
167-
//todo: Test this
168159
include::partial$/algorithms/common-configuration/common-parameters.adoc[]
169160

170161
.Configuration
@@ -182,7 +173,6 @@ include::partial$/algorithms/common-configuration/common-mutate-configuration-en
182173
| nodePropertiesWritten | Integer | Number of properties written to Neo4j.
183174
| preProcessingMillis | Integer | Milliseconds for preprocessing the graph.
184175
| computeMillis | Integer | Milliseconds for running the algorithm.
185-
| postProcessingMillis | Integer | Milliseconds for computing the global metrics.
186176
| writeMillis | Integer | Milliseconds for writing results back to Neo4j.
187177
| configuration | Map | The configuration used for running the algorithm.
188178
|===
@@ -252,7 +242,6 @@ In the following examples we will demonstrate using the Clique Counting algorith
252242
[[algorithms-clique-counting-examples-stream]]
253243
=== Stream
254244

255-
// :stream-details: For example, we can order the results to find the nodes with the highest triangle count. // todo
256245
include::partial$/algorithms/shared/examples-stream-intro.adoc[]
257246

258247
.The following will run the algorithm in `stream` mode:
@@ -261,24 +250,23 @@ include::partial$/algorithms/shared/examples-stream-intro.adoc[]
261250
[source, cypher, role=noplay]
262251
----
263252
CALL gds.cliqueCounting.stream('myGraph')
264-
YIELD nodeId, perNodeCount
265-
RETURN gds.util.asNode(nodeId).name AS name, perNodeCount
253+
YIELD nodeId, counts
254+
RETURN gds.util.asNode(nodeId).name AS name, counts
255+
ORDER BY name ASC
266256
----
267-
// ORDER BY triangleCount DESC, name ASC //fixme
268-
//todo: Test this
269257
.Results
270258
[opts="header",cols="1,1"]
271259
|===
272-
| name | perNodeCount
273-
| "Chris" | [4,1]
274-
| "Karin" | [4,1]
275-
| "Alice" | [3,1]
276-
| "Michael" | [3,1]
260+
| name | counts
261+
| "Alice" | [3, 1]
262+
| "Chris" | [4, 1]
263+
| "Karin" | [4, 1]
264+
| "Mark" | []
265+
| "Michael" | [3, 1]
277266
| "Will" | [1]
278-
| "Mark" | [ ]
279267
|===
280268
--
281-
Here we find that the 'Chris' node is part of 4 triangles and a four-clique, while the 'Will' node is part of only a triangle. This can be verified in the xref:algorithms/clique-counting.adoc#algorithms-clique-counting-examples[example graph]. Since the 'Dan' node is linked only to Bob, it is not part of any clique of size three or larger and we therefore get an empty list.
269+
Here we find that the 'Chris' node is part of 4 triangles and a four-clique, while the 'Will' node is part of only a triangle. This can be verified in the xref:algorithms/clique-counting.adoc#algorithms-clique-counting-examples[example graph]. Since the 'Mark' node is linked only to the 'Will' node, it is not part of any clique of size three or larger and we therefore get an empty list.
282270

283271
Note that with a clique of size k, you are guaranteed to have a clique also of size k-1 since any subset of a clique is also a clique.
284272

@@ -299,12 +287,11 @@ include::partial$/algorithms/shared/examples-stats-intro.adoc[]
299287
CALL gds.cliqueCounting.stats('myGraph')
300288
YIELD globalCount
301289
----
302-
//todo: Test this
303290
.Results
304291
[opts="header"]
305292
|===
306293
| globalCount
307-
| [5,1]
294+
| [5, 1]
308295
|===
309296
--
310297

@@ -317,7 +304,6 @@ In other words, that node is part of most cliques in the graph and thus has a ve
317304
[[algorithms-clique-counting-examples-mutate]]
318305
=== Mutate
319306

320-
// :mutate-details: For example, using the clique counting to compute the xref:algorithms/local-clustering-coefficient.adoc#algorithms-local-clustering-coefficient-examples-pre-computed[local clustering coefficient].
321307
include::partial$/algorithms/shared/examples-mutate-intro.adoc[]
322308

323309
[role=query-example]
@@ -330,13 +316,12 @@ CALL gds.cliqueCounting.mutate('myGraph', {
330316
})
331317
YIELD globalCount
332318
----
333-
//todo: test this
334319

335320
.Results
336321
[opts="header"]
337322
|===
338323
| globalCount
339-
| [5,1]
324+
| [5, 1]
340325
|===
341326
--
342327

@@ -361,13 +346,12 @@ CALL gds.cliqueCounting.write('myGraph', {
361346
})
362347
YIELD globalCount
363348
----
364-
//todo: Test this
365349

366350
.Results
367351
[opts="header"]
368352
|===
369353
| globalCount
370-
| [5,1]
354+
| [5, 1]
371355
|===
372356
--
373357

proc/community/src/integrationTest/java/org/neo4j/gds/cliquecounting/CliqueCountingMutateProcTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void testMutate() {
124124
var rowCount=runQueryWithRowConsumer(query, row -> {
125125
assertThat(row.getNumber("preProcessingMillis").longValue()).isGreaterThanOrEqualTo(0);
126126
assertThat(row.getNumber("computeMillis").longValue()).isGreaterThanOrEqualTo(0);
127-
assertThat(row.getNumber("nodeCount").longValue()).isEqualTo(5);
127+
assertThat(row.getNumber("nodePropertiesWritten").longValue()).isEqualTo(5);
128128
assertThat((List<Long>) row.get("globalCount")).containsExactly(5L,1L);
129129
});
130130

@@ -152,10 +152,10 @@ void testMutateEstimate() {
152152
String query = GdsCypher.call(CLIQUE_COUNTING_GRAPH).algo("gds.cliqueCounting")
153153
.mutateEstimation()
154154
.addParameter("mutateProperty", "globalCount")
155-
.yields("nodeCount", "bytesMin", "bytesMax", "requiredMemory");
155+
.yields("nodePropertiesWritten", "bytesMin", "bytesMax", "requiredMemory");
156156

157157
assertCypherResult(query, List.of(Map.of( //todo
158-
"nodeCount", 4L,
158+
"nodePropertiesWritten", 4L,
159159
"bytesMin", 544L,
160160
"bytesMax", 544L,
161161
"requiredMemory", "544 Bytes"
@@ -277,7 +277,7 @@ void testRunOnEmptyGraph() {
277277
var rowCount=runQueryWithRowConsumer(query, row -> {
278278
AssertionsForClassTypes.assertThat(row.getNumber("preProcessingMillis").longValue()).isNotEqualTo(-1);
279279
AssertionsForClassTypes.assertThat(row.getNumber("computeMillis").longValue()).isEqualTo(-1);
280-
AssertionsForClassTypes.assertThat(row.getNumber("nodeCount").longValue()).isEqualTo(0);
280+
AssertionsForClassTypes.assertThat(row.getNumber("nodePropertiesWritten").longValue()).isEqualTo(0);
281281
AssertionsForClassTypes.assertThat(((List<Long>) row.get("globalCount")).size()).isEqualTo(0);
282282
});
283283

proc/community/src/integrationTest/java/org/neo4j/gds/cliquecounting/CliqueCountingStatsProcTest.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ void testStats() {
8686
var rowCount=runQueryWithRowConsumer(query, row -> {
8787
assertThat(row.getNumber("preProcessingMillis").longValue()).isGreaterThanOrEqualTo(0);
8888
assertThat(row.getNumber("computeMillis").longValue()).isGreaterThanOrEqualTo(0);
89-
assertThat(row.getNumber("nodeCount").longValue()).isEqualTo(5);
9089
Assertions.assertThat((List<Long>) row.get("globalCount")).containsExactly(4L,1L);
9190
});
9291

@@ -115,7 +114,6 @@ void testRunOnEmptyGraph() {
115114
var rowCount=runQueryWithRowConsumer(query, row -> {
116115
assertThat(row.getNumber("preProcessingMillis").longValue()).isNotEqualTo(-1);
117116
assertThat(row.getNumber("computeMillis").longValue()).isEqualTo(-1);
118-
assertThat(row.getNumber("nodeCount").longValue()).isEqualTo(0);
119117
Assertions.assertThat(((List<Long>) row.get("globalCount")).size()).isEqualTo(0);
120118
});
121119

proc/community/src/integrationTest/java/org/neo4j/gds/cliquecounting/CliqueCountingWriteProcTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void testWriting() {
9999
assertThat(row.getNumber("preProcessingMillis").longValue()).isGreaterThanOrEqualTo(0);
100100
assertThat(row.getNumber("computeMillis").longValue()).isGreaterThanOrEqualTo(0);
101101
assertThat(row.getNumber("writeMillis").longValue()).isGreaterThanOrEqualTo(0);
102-
assertThat(row.getNumber("nodeCount").longValue()).isEqualTo(5);
102+
assertThat(row.getNumber("nodePropertiesWritten").longValue()).isEqualTo(5);
103103
Assertions.assertThat((List<Long>) row.get("globalCount")).containsExactly(4L, 1L);
104104
assertUserInput(row, "writeProperty", "perNodeCount");
105105

@@ -163,7 +163,7 @@ void testRunOnEmptyGraph() {
163163
var rowCount=runQueryWithRowConsumer(query, row -> {
164164
AssertionsForClassTypes.assertThat(row.getNumber("preProcessingMillis").longValue()).isNotEqualTo(-1);
165165
assertThat(row.getNumber("computeMillis").longValue()).isEqualTo(-1);
166-
assertThat(row.getNumber("nodeCount").longValue()).isEqualTo(0);
166+
assertThat(row.getNumber("nodePropertiesWritten").longValue()).isEqualTo(0);
167167
Assertions.assertThat((List<Long>) row.get("globalCount")).isEmpty();
168168
});
169169

procedures/facade-api/community-facade-api/src/main/java/org/neo4j/gds/procedures/algorithms/community/CliqueCountingMutateResult.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public record CliqueCountingMutateResult(
3030
long preProcessingMillis,
3131
long computeMillis,
3232
long mutateMillis,
33-
long nodeCount,
33+
long nodePropertiesWritten,
3434
List<Long> globalCount,
3535
Map<String, Object> configuration
3636
) implements ModeResult {

procedures/facade-api/community-facade-api/src/main/java/org/neo4j/gds/procedures/algorithms/community/CliqueCountingStatsResult.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
public record CliqueCountingStatsResult(
3131
long preProcessingMillis,
3232
long computeMillis,
33-
long nodeCount,
3433
List<Long> globalCount,
3534
Map<String, Object> configuration
3635
) implements ModeResult {
@@ -45,7 +44,6 @@ public static CliqueCountingStatsResult create(
4544
return new CliqueCountingStatsResult(
4645
timings.preProcessingMillis,
4746
timings.computeMillis,
48-
nodeCount,
4947
Arrays.stream(globalCount).boxed().toList(),
5048
configurationMap
5149
);
@@ -59,7 +57,6 @@ static Stream<CliqueCountingStatsResult> emptyFrom(
5957
new CliqueCountingStatsResult(
6058
timings.preProcessingMillis,
6159
timings.computeMillis,
62-
0,
6360
List.of(),
6461
configurationMap
6562
)

procedures/facade-api/community-facade-api/src/main/java/org/neo4j/gds/procedures/algorithms/community/CliqueCountingWriteResult.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,22 @@ public record CliqueCountingWriteResult(
3030
long preProcessingMillis,
3131
long computeMillis,
3232
long writeMillis,
33-
long nodeCount,
33+
long nodePropertiesWritten,
3434
List<Long> globalCount,
3535
Map<String, Object> configuration
3636
) implements ModeResult {
3737

3838
public static CliqueCountingWriteResult create(
3939
AlgorithmProcessingTimings timings,
40-
long nodeCount,
40+
long nodePropertiesWritten,
4141
long[] globalCount,
4242
Map<String, Object> configurationMap
4343
) {
4444
return new CliqueCountingWriteResult(
4545
timings.preProcessingMillis,
4646
timings.computeMillis,
4747
timings.sideEffectMillis,
48-
nodeCount,
48+
nodePropertiesWritten,
4949
Arrays.stream(globalCount).boxed().toList(),
5050
configurationMap
5151
);

0 commit comments

Comments
 (0)