Skip to content
Developer Edition runs on one host and does not require a product license file. Need multi-host deployment or performance testing at scale? Explore Enterprise Edition

TopKAgg

A TopKAgg aggregate value variable (TopKAgg<K, SortFields>) maintains the top K records based on specified sort fields (SortFields). This variable automatically retains the top K records sorted according to the sort rule (ascending or descending) and discards other records when the number of records exceeds K.

Declaration syntax

topk_agg_declaration
NODE VALUE aggregator_value_variable TopKAgg < top_k , sort_field data_type ASC ASCENDING DESC DESCENDING NULLS FIRST NULLS LAST , >

topk_agg_declaration ::=
    'NODE'? 'VALUE' aggregator_value_variable 'TopKAgg' '<' top_k ',' (sort_field data_type ( 'ASC' | 'ASCENDING' | 'DESC' | 'DESCENDING' )? ('NULLS FIRST' | 'NULLS LAST')? ) (',' (sort_field data_type ( 'ASC' | 'ASCENDING' | 'DESC' | 'DESCENDING' )? ('NULLS FIRST' | 'NULLS LAST')? ))* '>'

Parameters

The following are the specific parameters for TopKAgg aggregator value variables. For information about other parameters in the declaration syntax, see Parameters.

top_k

The maximum number of records to be retained. The value must be an integer greater than 0.

sort_field

The field used for sorting. The input must contain matching fields.

data_type

The data type of the sorting field. The following data types are supported for sorting:

ASC | ASCENDING | DESC | DESCENDING

The sorting rule:

  • ASC/ASCENDING (default): Sort values in ascending order.
  • DESC/DESCENDING: Sort values in descending order.

If there are multiple sort fields, records are first sorted by the first sort field. If the values in the first sort field are identical, records are then sorted by the second sort field, and so on.

For information about the comparison rules for values of each data type, see comp_op.

NULLS FIRST | NULLS LAST

The order of null values in the sorting results.

  • NULLS FIRST: null values are placed at the beginning of the sorting results. This is the default value when the sorting rule is set to DESC or DESCENDING.
  • NULLS LAST: null values are placed at the end of the sorting results. This is the default value when the sorting rule is set to ASC or ASCENDING.

Initial value

As indicated in the declaration syntax, an initial value must not be specified during declaration.

Input type and supported operations

The following table summarizes the input types and corresponding operations supported by TopKAgg aggregate value variables:

Input type Assignment Aggregation
Record (RECORD) ❌ ✅
Record list (LIST<RECORD>) ✅ ❌
TopKAgg aggregate value variable (TopKAgg<K, SortFields>) ✅ ✅

TopKAgg aggregate value variables support aggregation (+=) and assignment (=) operations.

  • Assignment operation (=): The input on the right must be a record list or a TopKAgg aggregation value variable.
    • If the input is a record list, the assignment operation replaces the contents of the target variable with records from the list. The fields of the records must match the sorting fields declared. After replacement, only the top K records determined by the sorting rules are retained.
    • If the input is a TopKAgg aggregate value variable of the same type, the assignment operation copies the records from the variable and replaces the contents of the target variable. Only the top K records after sorting are retained in the result.
  • Aggregation operation (+=): The input on the right must be a record or TopKAgg aggregated value variable.
    • If the input is a single record, the aggregation operation adds it to the target variable. The fields of the record must match the sorting fields, and only the top K records after sorting are retained.
    • If the input is a TopKAgg aggregation value variable of the same type, all records are merged into the target variable, and only the top K records sorted according to the sorting rules are retained.

Return type

TopKAgg<K, SortFields> -> LIST<RECORD>

The return type is a list consisting of the top K records sorted according to the sorting rules.

Member functions

This section introduces the member functions supported by TopKAgg aggregate value variables.

size()

Returns the number of records held by a TopKAgg aggregate value variable.

Function signature

size() -> UINT64

clear()

Removes all records held by a TopKAgg aggregate value variable.

Function signature

clear() -> VOID

min()

Returns the last record held by a TopKAgg aggregate value variable after sorting according to the sorting rules. For example, if the list of records [RECORD{test:1}, RECORD{test:2}, RECORD{test:3}] is sorted in ascending order by the test field, min() returns RECORD{test:3}, which is the last record in the sorted list.

Function signature

min() -> RECORD

Examples

The following examples are based on the temporary graph #movie_temporary_graph created in CREATE TEMPORARY GRAPH.

Global TopKAgg aggregator value variables

'''
USE #movie_temporary_graph {
  VALUE global_topk TopKAgg<3, test INT ASC>  // Define a TopK aggregator variable that keeps the 3 smallest test values
  VALUE global_topk2 TopKAgg<2, test INT DESC>  // Define another TopKAgg aggregator variable that keeps the 2 largest test values

  SET @global_topk += RECORD{test:1}    // topk: [RECORD{test:1}]
  SET @global_topk += RECORD{test:3}    // topk: [RECORD{test:1}, RECORD{test:3}]
  SET @global_topk += RECORD{test:4}    // topk: [RECORD{test:1}, RECORD{test:3}, RECORD{test:4}]
  SET @global_topk += RECORD{test:2}    // topk: [RECORD{test:1}, RECORD{test:2}, RECORD{test:3}] (4 is discarded)
  SET @global_topk += RECORD{test:-1}   // topk: [RECORD{test:-1}, RECORD{test:1}, RECORD{test:2}] (3 is discarded)
  LOG_INFO("@global_topk: ", @global_topk)

  SET @global_topk2 += RECORD{test:10}
  SET @global_topk2 += RECORD{test:5}
  SET @global_topk2 += RECORD{test:15}
  LOG_INFO("@global_topk2: ", @global_topk2)

  // Assignment from a list of records
  // Will keep the 3 smallest: [RECORD{test:3}, RECORD{test:5}, RECORD{test:8}]
  SET @global_topk = LIST[RECORD{test:10}, RECORD{test:5}, RECORD{test:15}, RECORD{test:8}, RECORD{test:3}]   
  LOG_INFO("TopK from LIST assignment: ", @global_topk)

  // Assignment from an empty list
  SET @global_topk = []
  LOG_INFO("TopK from empty LIST: ", @global_topk)   // Output: []

  // Assign global_topk2 to global_topk
  SET @global_topk = @global_topk2
  LOG_INFO("TopK from global_topk2: ", @global_topk)   // Output: [RECORD{test:10}, RECORD{test:15}]

  // Member functions
  LOG_INFO("Size: ", @global_topk.size())   // Check the number of records
  LOG_INFO("Min: ", @global_topk.min())   // View the last record in the sorted list

  SET @global_topk.clear()   // Clear the TopK aggregator variable
  LOG_INFO("Clear the TopK aggregator: ", @global_topk) 
}
'''

Return:

Log:
2025-08-22T11:31:41.456183 INFO  - @global_topk: [{test:-1},{test:1},{test:2}]
2025-08-22T11:31:41.457019 INFO  - @global_topk2: [{test:15},{test:10}]
2025-08-22T11:31:41.457372 INFO  - TopK from LIST assignment: [{test:3},{test:5},{test:8}]
2025-08-22T11:31:41.457667 INFO  - TopK from empty LIST: []
2025-08-22T11:31:41.457955 INFO  - TopK from global_topk2: [{test:10},{test:15}]
2025-08-22T11:31:41.458123 INFO  - Size: 2
2025-08-22T11:31:41.458309 INFO  - Min: {test:15}
2025-08-22T11:31:41.458631 INFO  - Clear the TopK aggregator: []

Node-attached TopKAgg aggregator value variables

'''
USE #movie_temporary_graph {
  // Define a TopK aggregator for each node, keeping top 2 records
  // Sort by score in descending order, then by neighbor ID in descending order if scores are equal
  NODE VALUE node_topk TopKAgg<2, score DOUBLE DESC, neigh_id INT DESC>  

  // Match paths from User nodes (with IDs 1, 3, 4) to Movie nodes via Watch relationships
  MATCH (a@User WHERE a.id IN [1,3,4])-[w@Watch]->(b@Movie)
  PER PATH {
    // For each matched path, add a record containing rating and movie ID to the user's TopK aggregator
    SET a.@node_topk += RECORD{score: w.rate, neigh_id: b.id}
  }
  PER NODE (a) {
    LOG_INFO("a.id: ", a.id, " a.@node_topk: ", a.@node_topk)
  }
}
'''

Return:

Log:
2025-08-23T08:23:53.020313 INFO  - a.id: 4 a.@node_topk: [{neigh_id:104,score:5},{neigh_id:99,score:5}]
2025-08-23T08:23:53.020313 INFO  - a.id: 3 a.@node_topk: [{neigh_id:473,score:4.5},{neigh_id:152,score:3}]
2025-08-23T08:23:53.020313 INFO  - a.id: 1 a.@node_topk: [{neigh_id:651,score:5},{neigh_id:601,score:5}]