ArangoDB 查找Arango中每组的前N个条目

vatpfxk5  于 2022-12-09  发布在  Go
关注(0)|答案(1)|浏览(186)

我试图在Arango(AQL)中按组高效地查找顶部条目。我有一个相当标准的对象集合和一个表示部门和该部门中雇员的边缘集合。
示例用途:找出每个部门中经验最多的前2名员工。

样本数据:

“departments”是一个对象集合。下面是一些条目:
| 识别码(_I)|姓名|
| - -|- -|
| 部门/1|工程学|
| 部门/2|销售额|
“dept_emp_edges”是通过id连接部门和雇员对象的边集合。
| 识别码(_I)|来自(_F)|至(_T)|年_到期日|
| - -|- -|- -|- -|
| 部门雇员边缘/1|部门/1|员工/1|三个|
| 部门_雇员_边缘/2|部门/1|员工/2|四个|
| 部门_雇员_边缘/3|部门/1|员工/3|五个|
| 部门雇员边缘/4|部门/2|员工/1|六个|
最后,我想选出每个部门最有经验的前2名员工:
| 部门|受雇人|年_到期日|
| - -|- -|- -|
| 部门/1|员工/3|五个|
| 部门/1|员工/2|四个|
| 部门/2|员工/1|六个|

长工作查询

下面的查询可以工作!但是在较大的表上有点慢,而且感觉效率很低。

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还不熟悉,我还能做些什么来确保它的效率?

pcrecxhr

pcrecxhr1#

你的第一个查询是不正确的书面(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-字段上的索引可能会有帮助(Explain建议这样做)。

相关问题