在 Arango 中查找每组的前 N 个条目
Posted
技术标签:
【中文标题】在 Arango 中查找每组的前 N 个条目【英文标题】:Finding top N entries per group in Arango 【发布时间】:2021-11-15 10:01:03 【问题描述】:我正在尝试在 Arango (AQL) 中按组有效地查找排名靠前的条目。我有一个相当标准的对象集合和一个代表该部门的部门和员工的边缘集合。
示例目的:找出每个部门中经验最多的前 2 名员工。
样本数据:
“部门”是一个对象集合。以下是一些条目:
_id | name |
---|---|
departments/1 | engineering |
departments/2 | sales |
“dept_emp_edges”是一个边集合,通过 ids 连接部门和员工对象。
_id | _from | _to | years_exp |
---|---|---|---|
dept_emp_edges/1 | departments/1 | employees/1 | 3 |
dept_emp_edges/2 | departments/1 | employees/2 | 4 |
dept_emp_edges/3 | departments/1 | employees/3 | 5 |
dept_emp_edges/4 | departments/2 | employees/1 | 6 |
我希望以大多数年的经验得到每个部门前 2 名的员工:
department | employee | years_exp |
---|---|---|
departments/1 | employee/3 | 5 |
departments/1 | employee/2 | 4 |
departments/2 | employee/1 | 6 |
长时间工作的查询
以下查询有效!但是在较大的表上有点慢,感觉效率低。
FOR dept IN departments
LET top2earners = (
FOR dep_emp_edge IN dept_emp_edges
FILTER dep_emp_edge._from == dept._id
SORT dep_emp_edge.years_exp DESC
LIMIT 2
RETURN 'department': dep_emp_edge._from,
'employee': dep_emp_edge._to,
'years_exp': dep_emp_edge.years_exp
)
FOR row in top2earners
return 'department': dep_emp_edge._from,
'employee': dep_emp_edge._to,
'years_exp': dep_emp_edge.years_exp
我不喜欢这样,因为这里有3个循环,感觉效率很低。
短查询
但是,我试着写:
FOR dept IN departments
FOR dep_emp_edge IN dept_emp_edges
FILTER dep_emp_edge._from == dept._id
SORT dep_emp_edge.years_exp DESC
LIMIT 2
RETURN 'department': dep_emp_edge._from,
'employee': dep_emp_edge._to,
'years_exp': dep_emp_edge.years_exp
但最后一个查询只输出最终部门的前 2 个结果。不是每个部门的所有前 2 名。
我的问题是:(1)为什么第二个较短的查询没有给出所有结果? (2) 我对 Arango 和 ArangoQL 还很陌生,我还可以做些什么来确保这有效?
【问题讨论】:
你能分享第一个查询的解释输出吗? 【参考方案1】:你的第一个查询写的不正确 (Query: AQL: collection or view not found: dep_emp_edge (while parsing)
) - 我只能猜到你的意思,我暂时忽略它。
您较小的查询将整体结果限制为两个 - 直观地相反 - 因为您没有按部门分组。
我建议一种稍微不同的方法:使用边缘集合作为中心源并按 _from 分组,每个部门返回一个文档,其中包含两个排名靠前的员工的数组(如果他们存在的话),而不是每个员工一个文档:
FOR edge IN dept_emp_edges
SORT edge.years_exp DESC
COLLECT dep = edge._from INTO deps
LET emps = (
FOR e in deps
LIMIT 2
RETURN ZIP(["employee", "years_exp"], [e.edge._to, e.edge.years_exp])
)
RETURN "department": dep, employees: emps
对于您的示例数据库,这将返回:
[
"department": "departments/1",
"employees": [
"employee": "employees/3",
"years_exp": 5
,
"employee": "employees/2",
"years_exp": 4
]
,
"department": "departments/2",
"employees": [
"employee": "employees/1",
"years_exp": 6
]
]
如果查询太慢,dept_emp_edges
集合的year_exp
字段上的索引可能会有所帮助(解释建议这样做)。
【讨论】:
以上是关于在 Arango 中查找每组的前 N 个条目的主要内容,如果未能解决你的问题,请参考以下文章