如何遍历以使用AQL获取特定类型的所有子项

问题描述 投票:0回答:1

我有一个代表游戏中等级的图表。我所拥有的节点类型的一些示例是“Level”,“Room”,“Chair”。这些类型由VertexCollections表示,其中一个集合称为“级别”等。它们通过来自单独EdgeCollections的边连接,例如“Level”-roomEdge->“Room”-chairEdge->“Chair”。房间也可以包含房间等,所以深度不明。

我想从任意“Level”-vertex开始并遍历整个子树并找到属于该级别的所有椅子。

我试图看看ArangoDB对我来说是否比OrientDB更好,在OrientDB中我使用了查询:

SELECT FROM (TRAVERSE out() FROM startNode) WHERE @class = 'Chair'

我尝试过AQL查询:

FOR v IN 1..6 OUTBOUND @startVertex GRAPH 'testDb' FILTER IS_SAME_COLLECTION('Chair', v) == true RETURN v;

然而,与OrientDB查询相比,它似乎执行得慢得多(约1秒vs~0.1秒)。

我用于查询的代码如下:

String statement = "FOR v IN 1..6 OUTBOUND @startVertex GRAPH 'testDb' FILTER IS_SAME_COLLECTION('Chair', v) == true RETURN v";
timer.start();
ArangoCursor<BaseDocument> cursor = db.query(statement, new MapBuilder().put("startVertex", "Level/"+startNode.getKey()).get(), BaseDocument.class);
timer.saveTime();

两种解决方案都在相同的硬件上运行而没有进行任何优化,两个数据库都是“开箱即用”的。两种情况都使用相同的数据(约100万个顶点)并返回相同的结果。

所以我的问题是,如果我在AQL查询中正确地做事,或者有更好的方法吗?我是否误解了VertexCollections的概念以及如何使用它们?

arangodb
1个回答
0
投票

您是否有理由为每种实体类型设置多个集合,例如一个集合用于房间,一个用于级别,一个用于椅子?

一种选择是拥有一个包含您的实体的集合,并使用文档中的type: "Chair"type: "Level"键来标识它的实体类型。

然后你有一个单一的关系集合,它保持实体集合的_to_from边缘。

然后,您可以从给定节点(例如Level)开始,并使用以下查询查找与其连接的所有Chair类型的实体:

FOR v, e, p IN 1..6 OUTBOUND Level_ID Relationship_Collection
FILTER p.vertices[-1].Type == 'Chair'
RETURN v

您可以返回v(最终顶点)或e(最终边缘)或p(所有路径)。

我不确定您是否需要使用图形对象,而是使用可以为实体集合添加关系的关系集合。

如果需要,图表很好,但对于遍历查询不是必需的。阅读ArangoDB上的文档,看看是否需要它们,通常我不使用它们,因为使用图表可能会降低性能。

请记住查看索引,并使用UI中的“Explain”功能查看索引的使用方式。也许在'Type'键中添加一个哈希索引。

© www.soinside.com 2019 - 2024. All rights reserved.