Как пройти, чтобы получить все дочерние элементы определенного типа, используя AQL - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть график, отображающий уровни в игре. Вот некоторые примеры типов узлов: «Уровень», «Комната», «Стул». Типы представлены VertexCollections, где одна коллекция называется «Level» и т. Д. Они связаны ребрами из отдельных EdgeCollections, например «Level» -roomEdge-> «Room» -chairEdge-> «Chair». Комнаты могут также содержать комнаты и т. Д., Поэтому глубина неизвестна.

Я хочу начать с произвольной вершины уровня, пройти через все поддерево и найти все стулья, принадлежащие уровню.

Я пытаюсь понять, будет ли 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 секунда против ~ 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();

Оба решения работают на одном и том же оборудовании без какой-либо оптимизации, обе базы данных используются "из коробки". В обоих случаях используются одни и те же данные (~ 1 миллион вершин) и возвращаются одинаковые результаты.

Так что мой вопрос в том, правильно ли я делаю свои запросы в AQL или есть ли лучший способ сделать это? Я неправильно понял концепцию VertexCollections и как они используются?

1 Ответ

0 голосов
/ 13 апреля 2019

Существует ли причина, по которой у вас есть несколько коллекций для каждого типа сущности, например одна коллекция для комнат, одна для уровней, одна для стульев?

Один из вариантов - иметь одну коллекцию, содержащую ваши сущности, и вы определяете тип сущности с помощью клавиши type: "Chair" или type: "Level" в документе.

Затем у вас есть одна коллекция отношений, которая содержит ребра _to и _from коллекции сущностей.

Затем вы можете начать с данного узла (например, уровня) и найти все сущности типа 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, чтобы узнать, нужны ли они вам, обычно я ими не пользуюсь, так как использование графиков может немного снизить производительность.

Не забудьте посмотреть на индексы и использовать функцию «Объяснить» в пользовательском интерфейсе, чтобы увидеть, как используются ваши индексы. Возможно добавьте хеш-индекс к клавише «Тип».

...