Функции-предикаты

Предикаты — это булевы функции, возвращающие true или false для заданного набора входных значений. Чаще всего они используются в предложении WHERE запросов для фильтрации подграфов.

exists(property)

Функция exists(property) возвращает true, если указанное свойство существует у вершины, ребра или карты. Эта функция отличается от предложения EXISTS в подзапросе.

Синтаксис: exists(property)

Возвращаемое значение:

Булево значение типа agtype.

Параметры:

Имя Описание
property Свойство вершины или ребра.

Запрос:

SELECT *
FROM cypher('graph_name', $$MATCH (n)
     WHERE exists(n.surname)
     RETURN n.first_name, n.last_name
$$) as (first_name agtype, last_name agtype);

Результат:

first_name last_name
'John' 'Smith'
'Patty' 'Patterson'

EXISTS(path)

Функция EXISTS(path) возвращает true, если указанный шаблон пути совпадает хотя бы с одним путём в графе.

Примечание!
Известное ограничение подзапросов EXISTS
В YMatrix AGE подзапрос EXISTS, ссылающийся на переменные из внешней области видимости, может завершиться ошибкой:
ERROR: could not devise a query plan for the given query.

  • Условие возникновения:
    Ошибка возникает, когда EXISTS используется в предложении WHERE конструкции OPTIONAL MATCH, а шаблон EXISTS ссылается на переменную, объявленную до этого OPTIONAL MATCH.
  • Примеры:
    Завершается ошибкой: MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c) WHERE EXISTS((c)<-[:incs]-(a)) RETURN a, c;
    Выполняется успешно: MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c) WHERE EXISTS((c)<-[:incs]-()) RETURN a, c.
  • Причина:
    AGE транслирует OPTIONAL MATCH в SQL-конструкцию LATERAL LEFT JOIN, а EXISTS — в SQL-подзапрос EXISTS SubLink. При ссылке EXISTS на переменную из внешней области возникает глубоко вложенная структура: LATERAL-подзапрос, содержащий EXISTS SubLink, который ссылается на переменные на два уровня выше. Распределённый планировщик запросов YMatrix не может построить корректный план выполнения для таких многоранговых ссылок на внешние переменные — это ограничение базового распределённого планировщика.
  • Рекомендуемые обходные решения:
    1. Объедините шаблон EXISTS непосредственно в паттерн OPTIONAL MATCH:
      MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c)<-[:incs]-(a) RETURN a, c;
    2. Разделите запрос на несколько шагов, чтобы избежать ссылки на внешние переменные внутри EXISTS в рамках OPTIONAL MATCH:
      MATCH (a:A) WITH a OPTIONAL MATCH (a)-[:incs]->(c) WITH a, c WHERE c IS NULL OR EXISTS((c)<-[:incs]-()) RETURN a, c.

Примечание!
Область действия ограничения: Это ограничение действует только при одновременном выполнении всех следующих условий:

  1. Используется OPTIONAL MATCH (порождающий LATERAL LEFT JOIN);
  2. EXISTS применяется в его предложении WHERE;
  3. Шаблон EXISTS ссылается на переменную из внешней области видимости данного OPTIONAL MATCH.

EXISTS в обычных конструкциях MATCH, проверки существования свойств (EXISTS(n.prop)) и шаблоны EXISTS, не ссылающиеся на внешние переменные, работают без ограничений.

Запрос:

SELECT *
FROM cypher('graph_name', $$
     MATCH (n)
     WHERE exists((n)-[]-({name: 'Willem Defoe'}))
     RETURN n.full_name
$$) as (full_name agtype);

Результат:

full_name
'Toby Maguire'
'Tom Holland'