Triangle Count

Introduction

The Triangle Count algorithm counts the number of triangles for each node in the graph. A triangle is a set of three nodes where each node has a relationship to the other two. In graph theory terminology, this is sometimes referred to as a 3-clique. The Triangle Count algorithm in the Neo4j Graph Analytics app only finds triangles in undirected graphs.

Triangle counting has gained popularity in social network analysis, where it is used to detect communities and measure the cohesiveness of those communities. It can also be used to determine the stability of a graph, and is often used as part of the computation of network indices, such as clustering coefficients.

For more information on this algorithm, see:

Node label filtering

For some use-cases it is useful to only count triangles that contain nodes with specific node labels. This is also something that can save computation time, as the algorithm will not have to consider nodes that do not have the specified labels.

The algorithm supports node label filtering by allowing you to specify a list of up to three node labels in the configuration. If three labels are specified, the algorithm will only count triangles that contain nodes with all three labels, and each label must be represented by at least one node in the triangle. If fewer than three labels are specified, the algorithm will count triangles where each specified label is represented by at least one node in the triangle, but nodes with no specified label can also be part of the triangle. If a label is repeated in the list, it will represented by as many nodes as times it appears in the list.

Syntax

This section covers the syntax used to execute the Triangle Count algorithm.

Run Triangle Count.
CALL Neo4j_Graph_Analytics.graph.triangle_count(
  'CPU_X64_XS',                    (1)
  {
    ['defaultTablePrefix': '...',] (2)
    'project': {...},              (3)
    'compute': {...},              (4)
    'write':   {...}               (5)
  }
);
1 Compute pool selector.
2 Optional prefix for table references.
3 Project config.
4 Compute config.
5 Write config.
Table 1. Parameters
Name Type Default Optional Description

computePoolSelector

String

n/a

no

The selector for the compute pool on which to run the Triangle Count job.

configuration

Map

{}

no

Configuration for graph project, algorithm compute and result write back.

The configuration map consists of the following three entries.

For more details on below Project configuration, refer to the Project documentation.
Table 2. Project configuration
Name Type

nodeTables

List of node tables.

relationshipTables

Map of relationship types to relationship tables.

Table 3. Compute configuration
Name Type Default Optional Description

mutateProperty

String

'triangles'

yes

The node property that will be written back to the Snowflake database.

relationshipWeightProperty

String

null

yes

Name of the relationship property to use as weights. If unspecified, the algorithm runs unweighted.

seedProperty

String

n/a

yes

Used to set the initial component for a node. The property value needs to be a number.

threshold

Float

null

yes

The value of the weight above which the relationship is considered in the computation.

maxDegree

Integer

2^63 - 1

yes

Maximum degree of a node to be considered in triangle counting. Nodes with degree higher than this value will be excluded and get assigned a triangle count of -1.

labelFilter

List of String

[]

yes

A list of up to three node labels as strings. Only triangles with nodes having representatives for each specified label will be counted. If left empty (default), all triangles will be counted.

For more details on below Write configuration, refer to the Write documentation.
Table 4. Write configuration
Name Type Default Optional Description

nodeLabel

String

n/a

no

Node label in the in-memory graph from which to write a node property.

nodeProperty

String

'triangles'

yes

The node property that will be written back to the Snowflake database.

outputTable

String

n/a

no

Table in Snowflake database to which node properties are written.

Examples

In this section we will show examples of running the Triangle Count algorithm on a concrete graph. The intention is to illustrate what the results look like and to provide a guide in how to make use of the algorithm in a real setting. We will do this on a small social network graph of a handful nodes connected in a particular pattern. The example graph looks like this:

Visualization of the example graph
The following SQL statement will create the example graph tables in the Snowflake database:
CREATE OR REPLACE TABLE EXAMPLE_DB.DATA_SCHEMA.PERSON (NODEID VARCHAR);
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.PERSON VALUES
  ('Alice'),
  ('Michael'),
  ('Karin'),
  ('Chris'),
  ('Will'),
  ('Mark');

CREATE OR REPLACE TABLE EXAMPLE_DB.DATA_SCHEMA.KNOWS (SOURCENODEID VARCHAR, TARGETNODEID VARCHAR);
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.KNOWS VALUES
  ('Michael', 'Karin'),
  ('Michael', 'Chris'),
  ('Will', 'Michael'),
  ('Mark', 'Michael'),
  ('Mark', 'Will'),
  ('Alice', 'Michael'),
  ('Will', 'Chris'),
  ('Chris', 'Karin');

This graph has several triangles formed by the relationships between nodes. For example, there is a triangle between Michael, Chris, and Karin, as they are all connected to each other. The algorithm will count these triangles for each node.

In the following example, we will demonstrate using the Triangle Count algorithm on this graph.

Run job

Running a triangle count job involves the three steps: Project, Compute and Write.

To run the query, there is a required setup of grants for the application, your consumer role and your environment. Please see the Getting started page for more on this.

We also assume that the application name is the default Neo4j_Graph_Analytics. If you chose a different app name during installation, please replace it with that.

The following will run a Triangle Count job:
CALL Neo4j_Graph_Analytics.graph.triangle_count('CPU_X64_XS', {
  'defaultTablePrefix': 'EXAMPLE_DB.DATA_SCHEMA',
  'project': {
    'nodeTables': ['PERSON'],
    'relationshipTables': {
      'KNOWS': {
        'sourceTable': 'PERSON',
        'targetTable': 'PERSON',
        'orientation': 'UNDIRECTED'
      }
    }
  },
  'compute': {},
  'write': [
    {
      'nodeLabel': 'PERSON',
      'outputTable': 'TRIANGLE_COUNT_BY_PERSON'
    }
  ]
});
Table 5. Results
JOB_ID JOB_START JOB_END JOB_RESULT

job_492026bbeaa6422eb4502a18def04cd6

2025-04-30 13:53:53.702000

2025-04-30 13:54:00.716000

 {
  "project_1": {
    "graphName": "snowgraph",
    "nodeCount": 6,
    "nodeMillis": 218,
    "relationshipCount": 16,
    "relationshipMillis": 541,
    "totalMillis": 759
  },
   "triangle_count_1": {
     "computeMillis": 15,
     "configuration": {
       "concurrency": 2,
       "jobId": "4a766a5a-57ee-4438-bcca-9294a8bd6743",
       "logProgress": true,
       "maxDegree": 9223372036854775807,
       "mutateProperty": "triangles",
        "nodeLabels": [
          "*"
        ],
        "relationshipTypes": [
          "*"
        ],
       "sudo": false
     },
     "globalTriangleCount": 3,
     "mutateMillis": 3,
     "nodeCount": 6,
     "nodePropertiesWritten": 6,
     "postProcessingMillis": 0,
     "preProcessingMillis": 8
  },
  "write_node_property_1": {
    "exportMillis": 2268,
    "nodeLabel": "PERSON",
    "nodeProperty": "triangles",
    "outputTable": "EXAMPLE_DB.DATA_SCHEMA.TRIANGLE_COUNT_BY_PERSON",
    "propertiesExported": 6
  }
}

The returned result contains information about the job execution and result distribution. Additionally, the triangle count for each of the nodes has been written back to the Snowflake database. The job result indicates a global triangle count of 3, representing the total number of triangles in the graph. We can query the individual node triangle counts like so:

SELECT * FROM EXAMPLE_DB.DATA_SCHEMA.TRIANGLE_COUNT_BY_PERSON;
Table 6. Results
NODEID TRIANGLES

Alice

0

Michael

3

Karin

1

Chris

2

Will

2

Mark

1

The result shows that the algorithm identifies triangles in the graph. This can be verified in the example graph.