Source: https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/variable-definition/agg/topk_agg/ Documentation version: v5.3.2 # TopKAgg A TopKAgg aggregate value variable (`TopKAgg`) 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 diagramsource topk_agg_declaration ```` 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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/variable-definition/agg/#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: - [Numeric types](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-types/numeric-type/) - [Character string types](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-types/c-string-type/) - [Boolean types](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-types/boolean-type/) - [Temporal types](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-types/temporal-type/) ### `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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/fe/predicates/comparison/#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`) | ✅ | ❌ | TopKAgg aggregate value variable (`TopKAgg`) | ✅ | ✅ TopKAgg aggregate value variables support aggregation (`+=`) and assignment (`=`) operations. - Assignment operation (`=`): The input on the right must be a [record list](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-types/list-type/) 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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/data-types/record-type/) 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 -> LIST ```` 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](https://dev-docs.nebula-graph.io/v5.3.2/database-gql-reference/ddl/graph-projection/create/). ### 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}] ````