【问题标题】:Arangodb AQL queryArangodb AQL 查询
【发布时间】:2017-10-05 11:36:40
【问题描述】:

我的数据是这样组织的:

有 1k 名教师,10k 名学生,每个学生都有约 100 份作业。

我需要获取学生的所有作业,通过课程或通过他们之间的直接链接与老师相关。所有的顶点和边都有一些属性,假设所有需要的索引都已经建立,或者我们可以稍后讨论它们。

我可以通过足够快的查询获得所有需要的学生ID:

$query1 = "FOR v1 IN 1..1 INBOUND @teacherId teacher_pupil FILTER v1.deleted == false RETURN DISTINCT v1._id";
$query2 = "FOR v2 IN 2..2 INBOUND @teacherId OUTBOUND teacher_class, INBOUND pupil_class FILTER v2.deleted == false RETURN DISTINCT v2._id";
$queryUnion = "FOR x IN UNION_DISTINCT (($query1), ($query2)) RETURN x";

然后我写了以下内容:

$query = "
LET pupilIds = ($queryUnion)

FOR pupilId IN pupilIds
    LET homeworks = (
        FOR homework IN 1..1 ANY pupilId pupil_homework
            return [homework._id, pupilId]
    )  
RETURN homeworks";

我得到了我的作业,我什至可以尝试过滤它们,但是查询太慢了——我相信这是一种不正确的方式。

问题 1 如何在不一次将所有 Homeworks 大量内存(LIMIT 或其他)、按顶点属性快速高效地排序和过滤 Homeworks 的情况下做到这一点?我确信在查询/子查询的 FOR 中限制学生或与学生相关的作业会导致不正确的排序/分页。

我又尝试了纯图形 AQL 查询:

$query1 = "FOR v1 IN 2..2 INBOUND @teacherId pupil_teacher, OUTBOUND pupil_homework RETURN v1._id";
$query2 = "FOR v2 IN 3..3 INBOUND @teacherId teacher_class, pupil_class, OUTBOUND pupil_homework RETURN v2._id";
$query = "FOR x IN UNION_DISTINCT (($query1), ($query2)) LIMIT 500, 500 RETURN x";

速度也快不了多少,不知道怎么按属性过滤Teacher顶点。

问题 2 构建此类 AQL 查询的最佳方法是什么,如何访问按属性过滤所有路径部分的图的顶点?我可以对结果进行分页以节省内存并加快查询速度吗?我怎样才能加快速度?

谢谢!

【问题讨论】:

    标签: optimization graph query-optimization arangodb aql


    【解决方案1】:

    假设老师和学生通过班级(2个出站链接)或直接(单个出站链接)彼此相关,并且没有其他您可以这样做

     FOR v IN 1..2 OUTBOUND "teacher_id" GRAPH "graph_name"
       FILTER LIKE(v._id, "pupil_collection_name/%")
         FOR homeworks IN 1 OUTBOUND v GRAPH "graph_name"
            LIMIT lowerLimit,numberOfItems
               RETURN homeworks
    

    但是,如果老师和学生有可能通过班级以外的其他事物相互关联,我们将不得不过滤我们所看到的边缘的查询

     FOR v IN 1..2 OUTBOUND "teacher_id" GRAPH "graph_name"
       FILTER LIKE(v._id, "pupil_collection_name/%") && (e.name == "ClassPupil" || e.name == "TeacherPupil")
         FOR homeworks IN 1 OUTBOUND v GRAPH "graph_name"
            LIMIT lowerLimit,numberOfItems
               RETURN homeworks
    

    请注意,由于同一位老师可以直接与学生联系,也可以通过班级联系,我们可以有非唯一的作业。因此建议使用RETURN DISTINCT homeworks。但是如果重复不是问题,上面的查询应该可以工作

    【讨论】:

    • 感谢您的回答:查询速度非常快。如果我想按作业属性过滤怎么办?只需添加 ... FOR homeworks IN 1 OUTBOUND v GRAPH "graph_name" FILTER homeworks.attr1 == 'value1' LIMIT lowerLimit,numberOfItems RETURN homeworks ... 太慢了,而且据我所知,对于图形查询,ArangoDB 不使用顶点属性索引。
    • 如果您只是想通过作业属性过滤作业,您可以在作业集合中进行简单的循环,而无需使用图形查询。 FOR hw in home_work_collection_name FILTER hw.attr1 == 'value1' return hw 。此外,建议您通过attr1 属性来索引您的收藏。完成过滤后的作业后,您可以遍历图表并相应地获取教师或班级的信息。相反(建议),您可以在上述答案的查询中添加filter。就在LIMIT lowerLimit,numberOfItems 线上方
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多