TopKAgg¶
TopKAgg 聚合值变量(TopKAgg<K, SortFields>)根据指定的排序字段(SortFields)维护前 K 条记录。该变量自动保留根据排序规则(升序或降序)排序后的前 K 条记录,并在记录数量超过 K 时丢弃其他记录。
声明语法¶
- 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')? ))* '>'
参数¶
以下是 TopKAgg 聚合器值变量的具体参数。关于声明语法中其他参数的详细信息,请参见参数。
top_k¶
要保留的记录的最大数量。该值必须为大于 0 的整数。
sort_field¶
用于排序的字段。输入中的字段必须与该字段相匹配。
data_type¶
排序字段的数据类型。支持排序的数据类型有:
ASC | ASCENDING | DESC | DESCENDING¶
排序规则:
ASC/ASCENDING:默认值,按升序排序值。DESC/DESCENDING:按降序排序值。
如果有多个排序字段,记录先按照第一个排序字段进行排序。如果第一个排序字段的取值相同,则按照第二个排序字段对记录进行排序,以此类推。
关于每种数据类型的值的比较规则,请参见 comp_op。
NULLS FIRST | NULLS LAST¶
排序结果中null值的位置。
NULLS FIRST:null值排在排序结果的开头。当排序规则为DESC或DESCENDING时,这是默认行为。NULLS LAST:null值排在排序结果的末尾。当排序规则为ASC或ASCENDING时,这是默认行为。
初始值¶
从声明语法中可见,声明时不能指定初始值。
输入类型与支持的操作¶
下表总结了 TopKAgg 聚合值变量支持的输入类型以及对应的操作:
| 输入类型 | 赋值 | 聚合 |
|---|---|---|
记录(RECORD) |
❌ | ✅ |
记录列表(LIST<RECORD>) |
✅ | ❌ |
TopKAgg 聚合值变量(TopKAgg<K, SortFields>) |
✅ | ✅ |
TopKAgg 聚合值变量支持聚合(+=)和赋值(=)操作。
- 赋值操作(
=):右侧输入须为记录列表或 TopKAgg 聚合值变量。- 若输入为记录列表,则赋值操作使用列表中的记录替换目标变量中的内容。记录的字段需与声明时的排序字段一致,替换后仅保留按排序规则确定的前 K 条记录。
- 若输入为同类型的 TopKAgg 聚合值变量,则赋值操作拷贝变量中的记录并替换目标变量内容,结果中仅保留排序后的前 K 条记录。
- 聚合操作(
+=):右侧输入须为记录或 TopKAgg 聚合值变量。- 若输入为单条记录,则聚合操作将其添加至目标变量中,该记录的字段需匹配排序字段,合并后仅保留排序后的前 K 条记录。
- 若输入为同类型的 TopKAgg 聚合值变量,则聚合操作将其中所有记录合并到目标变量中,最终仅保留按排序规则排序的前 K 条记录。
返回类型¶
TopKAgg<K, SortFields> -> LIST<RECORD>
返回类型为一组根据排序规则排序后的由前 K 条记录组成的列表。
成员函数¶
本节介绍 TopKAgg 聚合值变量支持的成员函数。
size()¶
返回 TopKAgg 聚合值变量中记录的数量。
函数签名¶
size() -> UINT64
clear()¶
清空 TopKAgg 聚合值变量中的所有记录。
函数签名¶
clear() -> VOID
min()¶
返回 TopKAgg 聚合值变量中根据排序规则排序后的最后一个记录。例如,如果列表记录[RECORD{test:1}, RECORD{test:2}, RECORD{test:3}]按照test字段升序排序,则min()返回最后一条记录RECORD{test:3}。
函数签名¶
min() -> RECORD
示例¶
以下示例基于 CREATE TEMPORARY GRAPH 中创建的临时图#movie_temporary_graph。
全局 TopKAgg 聚合值变量¶
'''
USE #movie_temporary_graph {
VALUE global_topk TopKAgg<3, test INT ASC> // 定义一个 TopK 聚合值变量,保留最小的 3 个 test 值的记录
VALUE global_topk2 TopKAgg<2, test INT DESC> // 定义另一个同类型 TopKAgg 聚合值变量,保留最大的 2 个 test 值的记录
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 被丢弃)
SET @global_topk += RECORD{test:-1} // topk: [RECORD{test:-1}, RECORD{test:1}, RECORD{test:2}] (3 被丢弃)
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)
// 从记录列表赋值
// 将保留最小的 3 个: [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)
// 从空记录列表赋值
SET @global_topk = []
LOG_INFO("TopK from empty LIST: ", @global_topk) // 输出: []
// 将 global_topk2 赋值给 global_topk
SET @global_topk = @global_topk2
LOG_INFO("TopK from global_topk2: ", @global_topk) // 输出: [RECORD{test:10}, RECORD{test:15}]
// 成员函数
LOG_INFO("Size: ", @global_topk.size()) // 查看记录数量
LOG_INFO("Min: ", @global_topk.min()) // 查看排序列表中的最后一个记录。
SET @global_topk.clear() // 清空 TopK 聚合值变量
LOG_INFO("Clear the TopK aggregator: ", @global_topk)
}
'''
返回:
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: []
点绑定 TopKAgg 聚合值变量¶
'''
USE #movie_temporary_graph {
// 为每个点定义一个 TopK 聚合器,保留前 2 条记录
// 首先按评分降序排序,如果评分相同则按邻居 ID 降序排序
NODE VALUE node_topk TopKAgg<2, score DOUBLE DESC, neigh_id INT DESC>
// 匹配从用户点(ID 为 1、3、4)通过观看关系指向电影点的路径
MATCH (a@User WHERE a.id IN [1,3,4])-[w@Watch]->(b@Movie)
PER PATH {
// 对于每条匹配的路径,将包含评分和电影 ID 的记录添加到用户的 TopK 聚合值变量中
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)
}
}
'''
返回:
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}]