AQL - обход графа - фильтрация по пути со сложным условием

Я хотел бы спросить, как лучше всего пройти по графу и вернуть только подграф на основе сложного условия, которое должно выполняться всеми узлами от корня до листьев. Другими словами, мне нужен какой-то механизм, чтобы, когда условие на любом промежуточном уровне не выполняется, обход останавливается (ни один вложенный узел не обрабатывается и не возвращается на вывод)

Скажем, у меня есть следующий график:

A -> B -> C (active=false) -> D

где я деактивировал узел C (обратите внимание, что флаг active = false означает, что деактивирован весь подграф, включая C и D).

Согласно документации, я могу легко создать такой фильтр с помощью фильтрации по пути, подстановочному знаку [*] и ключевому слову ALL, которое также прекращает обход, когда условие на C не выполняется. С простым условием это отлично работает:

for v,e,p in 1..100 outbound 'test/A' graph 'testGraph'
  filter p.vertices[*].active ALL != false return v
  // returns A, B

Теперь у меня есть еще один график, где каждый узел либо фиксирован, либо имеет атрибуты периода действия (от, до):

A (type="fixed") -> B (from=2,to=3) -> C (from=1, to=5) -> D (type="fixed")

Теперь я хотел бы вернуть только подграф, в котором все (промежуточные) узлы либо фиксированы, либо удовлетворяют условию времени от> = 2 до ‹= 3. Мне нужно, чтобы вернули A, B.

for v,e,p in 0..100 outbound 'test/A' graph 'testGraph'
  filter p.vertices[*].type ALL == 'fixed' or
    (p.vertices[*].from ALL >= 2 and p.vertices[*].from ALL <= 3)
  return v

Однако это явно неверно (и возвращает только A), логически мне нужно добавить ключевое слово ALL в начале условия (мне нужно, чтобы условие применялось на каждом уровне, и когда условие не выполняется, обход останавливается), однако это не поддерживается:

filter ALL(p.vertices[*].type == 'fixed' or
  (p.vertices[*].from >= 2 and p.vertices[*].from <= 3)

Классический подход через фильтрацию по вершинам не отвечает моим потребностям, потому что он не прекращает обход, когда условие не выполняется, то есть следующие возвращают A, B, D (C пропускается, но мне также нужно обрезать поддерево C таким образом, чтобы D не выводится):

for v,e,p in 0..100 outbound 'test/A' graph 'testGraph'
  filter  v.type == 'fixed' or 
    (v.from >= 2 and v.from <= 3)
  return v

Любые идеи? Спасибо.


person Pavel Rabek    schedule 01.09.2017    source источник
comment
Я не уверен насчет AQL, но вы можете составить свои собственные функции обхода / расширения / фильтрации графа. См .: docs.arangodb.com/3.3/Manual/Graphs/Traversals/ это может помочь решить проблему индивидуального подхода.   -  person kuza    schedule 28.02.2018


Ответы (1)


Функция AQL PRUNE была представлена ​​в версиях ArangoDB 3.4.5 и 3.5.0. При использовании ключевого слова AQL PRUNE обход останавливается, когда выполняется условие для вершины, ребра, пути или любой переменной, определенной ранее.

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

Этот видеоурок показывает разницу между FILTER и новым PRUNE на практическом примере. . Более подробную информацию можно найти в документации.

person Maximilian Kernbach    schedule 23.08.2019