Шаблоны графов GQL

Шаблоны графов — это основные стандартные блоки запросов GQL в графе в Microsoft Fabric. Они описывают структуры, которые вы ищете в графе с помощью узлов и ребер интуитивно понятным визуальным способом. Думайте о шаблонах графов как шаблонах, которые обработчик запросов пытается сопоставить с фактическими данными в графе.

В этой статье описываются правила синтаксиса и композиции для шаблонов графов в GQL.

Это важно

В этой статье исключительно используется пример графа социальных сетей.

Простые шаблоны элементов

Простые шаблоны элементов помогают соответствовать отдельным узлам и краям из графа, которые соответствуют определенным требованиям. Эти шаблоны формируют основу для более сложного сопоставления шаблонов.

Простые шаблоны узлов

Шаблон узла указывает метки и свойства, которые должен соответствовать узлу:

(:Place&City { name: "New York" })

Этот шаблон соответствует всем узлам, имеющим как метки, такPlace и City метки (указанные оператором & ) и свойства которых name равны "New York". Это сочетание обязательных меток и свойств называется заливкой шаблона узла.

Основные понятия:

  • Сопоставление меток: требуется & несколько меток.
  • Фильтрация свойств: укажите точные значения, которые должны соответствовать свойствам.
  • Гибкое сопоставление ("ковариантное") — соответствующие узлы могут иметь больше меток и свойств за пределами указанных.

Замечание

Узлы могут иметь несколько меток, но пограничные типы с несколькими метками пока не поддерживаются.

Простые шаблоны ребер

Шаблоны пограничных вычислений являются более сложными, чем шаблоны узлов. Они не только указывают заполнитель, но и связывают шаблон исходного узла с шаблоном целевого узла. Шаблоны пограничных вычислений описывают требования как к краю, так и к конечным точкам:

(:Person)-[:likes|knows { creationDate: ZONED_DATETIME("2010-08-31T13:16:54Z") }]->(:Comment)

Направление -[...]-> стрелки важно — оно определяет (:Person) как узор исходного узла и (:Comment) как узор целевого узла. Понимание направления пограничных вычислений имеет решающее значение для правильного запроса графа.

Эквивалентный зеркальный шаблон:

Вы можете перевернуть стрелку и переключить шаблоны узлов, чтобы создать эквивалентный зеркальный граничный шаблон:

(:Comment)<-[:likes { creationDate: ZONED_DATETIME("2010-08-31T13:16:54Z") }]-(:Person)

Этот шаблон находит те же отношения, но с противоположной точки зрения.

Шаблоны ребер, направленные на любой адрес

Если направление края графа не имеет значения для запроса, вы можете оставить его неуказаемым, создав любой направленный граничный шаблон:

(:Song)-[:inspired]-(:Movie)

Этот паттерн совпадает с теми же рёбрами, что (:Song)-[:inspired]->(:Movie) и (:Movie)-[:inspired]->(:Song) комбинированы, независимо от того, какой узел является началом и какой целевой (этот пример не относится к типу графа социальной сети).

Ярлыки шаблонов пограничных вычислений графа

GQL предоставляет удобные сочетания клавиш для распространенных пограничных шаблонов, чтобы сделать запросы более краткими:

  • ()->() ()-[]->() означает (направленный край с любой меткой)
  • ()<-() ()<-[]-() означает (направленный край в обратном направлении с любой меткой)
  • ()-() ()-[]-() означает (любой направленный край с любой меткой)

Эти сочетания клавиш могут быть полезны, если вы заботитесь о подключении, но не о конкретном типе пограничных графов.

Выражения меток

Шаблоны могут выражать сложные требования к меткам соответствующих узлов и ребер.

Example:

MATCH (:Person|(Organization&!Company))-[:isLocatedIn]->(p:City|Country)
RETURN count(*) AS num_matches

Это подсчитывает количество isLocatedIn ребер, подключающих Person узлы или Organizationузлы ,но неCompany - (которые всегда University являются узлами в схеме социальной сети) к City узлам или Country узлам.

Синтаксис

Синтаксис Meaning
A&B Метки должны включать как A, так и B.
A|B Метки должны включать по крайней мере одну из A или B.
!A Метки должны исключить A.

Кроме того, используйте скобки для управления порядком оценки выражений меток. По умолчанию ! имеет самый высокий приоритет и & имеет более высокий приоритет, чем |. Таким образом !A&B|C|!D , это то же самое, что ((!A)&B)|C|(!D)и .

Переменные привязки

Переменные позволяют ссылаться на соответствующие элементы графа в других частях запроса. Понимание того, как привязать и использовать переменные, важно для создания мощных запросов.

Переменные элемента привязки

Шаблоны узлов и ребер могут привязать соответствующие узлы и края к переменным для последующей ссылки.

(p:Person)-[w:workAt]->(c:Company)

В этом шаблоне p привязаны к соответствующим Person узлам, w к соответствующим workAt краям и c к соответствующим Company узлам.

Повторное использование переменной для структурных ограничений:

Повторное использование одной и той же переменной в шаблоне несколько раз выражает ограничение на структуру совпадений. Каждое вхождение одной переменной всегда должно быть привязано к одному элементу графа в допустимом совпадении. Повторное использование переменных является мощным для выражения сложных структурных требований.

(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)

Шаблон находит Person узлы x и y знает друг друга и работает в том же Companyрежиме, который привязан к переменной c. Повторное использование c гарантирует, что оба человека работают в одной компании.

Предикаты шаблона с переменными элемента:

Переменные элемента привязки позволяют указывать предикаты узлов и пограничных шаблонов. Вместо того, чтобы просто предоставить заливку с точными значениями свойств, например { name: "New York, USA" }, заливщик может указать предикат, который вычисляется для каждого элемента кандидата. Шаблон совпадает только в том случае, если предикат оценивается следующим способом TRUE:

(p:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T18:00:00Z")]-(o:Person)

Шаблон края находит людей, которые знали друг друга с 1 января 2000 года, используя гибкое условие, а не точное совпадение.

Замечание

Переменные шаблонов пограничных вычислений всегда привязываются к отдельному краю в предикате граничного шаблона, даже при использовании шаблонов переменной длины. Это может помочь не указать переменные списка пограничных групп для выполнения после фильтрации. См. раздел "Привязка переменных длины" для пограничных переменных шаблона.

Дополнительные методы предиката шаблонов:

Предикаты шаблонов предоставляют мощные встроенные возможности фильтрации, которые могут улучшить удобочитаемость запросов:

-- Multiple conditions in node predicates
MATCH (p:Person WHERE p.birthday < 19900101 AND p.gender = 'female')
      -[:workAt]->
      (c:Company WHERE c.name STARTS WITH 'A')

-- Filter on an edge property
MATCH (p1:Person)-[w:workAt WHERE w.workFrom >= 2010]->(c:Company)

-- MATCH WHERE: evaluated after pattern matching
MATCH (p:Person)-[:workAt]->(c:Company)
WHERE p.browserUsed = 'Firefox' AND c.name IS NOT NULL

-- Filter during matching and after
MATCH (p:Person WHERE p.gender = 'male')-[:workAt]->(c:Company)
WHERE p.birthday < 19900101 AND c.url IS NOT NULL

Подсказка

Держите предикат внутри паттерна, когда он описывает, какой узел или ребро может участвовать в матче.

Переменные пути привязки

Вы также можете привязать соответствующий путь к переменной пути для дальнейшей обработки или вернуть полную структуру пути пользователю:

p=(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)

p Здесь привязано к значению пути, представляющего полную структуру сопоставленного пути, включая ссылочные значения для всех узлов и ребер в указанном порядке.

Связанные пути могут быть либо возвращены пользователю, либо дополнительно обработаны с помощью функций, таких как NODES или EDGES:

MATCH p=(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)
LET path_edges = edges(p)
RETURN path_edges, size(path_edges) AS num_edges
GROUP BY path_edges

Создание шаблонов

В реальных запросах часто требуются более сложные шаблоны, чем простые структуры node-edge-node. GQL предоставляет несколько способов создания шаблонов для сложных обходов графов.

Создание шаблонов пути

Шаблоны пути можно создать путем объединения простых узлов и пограничных шаблонов для создания более длинных обходов.

(:Person)-[:knows]->(:Person)-[:workAt]->(:Company)-[:isLocatedIn]->(:Country)-[:isPartOf]->(:Continent)

Шаблон проходит от человека через свои социальные и профессиональные связи, чтобы найти, где находится компания своего коллеги.

Кусковая конструкция шаблона: Вы также можете создавать шаблоны путей более постепенно, что позволяет упростить чтение и понимание сложных шаблонов:

(:Person)-[:knows]->(p:Person),
(p:Person)-[:workAt]->(c:Company),
(c:Company)-[:isLocatedIn]->(:Country)-[:isPartOf]->(:Continent)

Этот подход разбивает один и тот же обход на логические шаги, что упрощает понимание и отладку.

Создание нелинейных шаблонов

Результирующая форма шаблона не должна быть линейным путем. Можно сопоставить более сложные структуры, такие как "звездообразующие" шаблоны, которые излучают от центрального узла:

(p:Person),
(p)-[:studyAt]->(u:University),
(p)-[:workAt]->(c:Company),
(p)-[:likes]-(m)

Шаблон находит человека вместе с их обучением, трудоустройством и предпочтениями содержимого одновременно — комплексный запрос профиля.

Паттерны в одном MATCH и том же случае не обязательно должны иметь общую переменную. Разрозненные паттерны образуют декартовое произведение их совпадения. Используйте переменную, когда шаблоны должны связывать один и тот же элемент графа, и останутся только объединённые комбинации.

Повторное использование управляющего элемента

GQL управляет повторяющимися узлами и рёбрами на двух уровнях:

  • Режим совпадения применяется к полному шаблону графа, включая пути, разделённые по запятым.
  • Режим пути применяется к одному пути.

Стандартный режим совпадения — REPEATABLE ELEMENTS. Он позволяет связывать один и тот же элемент в разных частях шаблона графа, в зависимости от режима пути каждого пути. Вы можете написать это явно:

REPEATABLE ELEMENTS (a)-[e1:knows]->(b), (a)-[e2:knows]->(c)

Используйте DIFFERENT EDGES или его синоним DIFFERENT RELATIONSHIPS , чтобы требовать уникальность рёбер по всему шаблону графа. Этот режим совпадения также изменяет любой WALK путь в паттерне к TRAIL поведению.

DIFFERENT EDGES (a)-[e1:knows]->(b), (a)-[e2:knows]->(c)

Следующие режимы пути управляют повторяющимися элементами в каждом пути:

Режим траектории Повторное использование элементов
WALK Узлы и рёбра могут повторяться.
TRAIL Рёбра не могут повторяться, но узлы могут повторяться.
SIMPLE Узлы не могут повторяться, кроме того, что первый и последний узлы могут быть одинаковыми. Края не могут повторяться.
ACYCLIC Узлы не могут повторять, включая первый и последний узлы. Края не могут повторяться.

WALK — это режим по умолчанию в режиме пути. При необходимости более строгой уникальности элементов префиксировать путь другим режимом:

Для и ACYCLIC, уникальность SIMPLE ребра вытекает из уникальности узла. SIMPLE Путь может замкнуться, вернувшись к своему первому узлу, но он всё равно не может повторно использовать ребро.

TRAIL (a)-[e1:knows]->(b)-[e2:knows]->(c)-[e3:knows]->(d)

Паттерн TRAIL даёт только совпадения, в которых e1, e2, и e3 отличаются. Узлы всё ещё могут повторяться, поэтому путь может образовывать цикл без повторного использования ребра.

Контролировать, какие пути возвращаются

Префикс поиска по пути управляет, какие пути возвращает паттерн пути. Префикс по умолчанию ALL возвращает все пути, соответствующие режиму и шаблону. Вы можете написать ALL явно:

ALL TRAIL (a:Person)-[:knows]->{1,4}(b:Person)

Используйте ANY SHORTEST для возврата одного самого короткого пути совпадения для каждой пары источник-назначение из каждой входной строки:

MATCH p = ANY SHORTEST
  (src:Person)-[:knows]->{1,4}(dst:Person)
RETURN src.id AS sourceId, dst.id AS targetId, path_length(p) AS hopCount
ORDER BY sourceId, targetId
LIMIT 100

Если несколько путей связываются на самой короткой длине, запрос возвращает один из них, но какой именно связан путь возвращается не является детерминированным. Нижняя граница нуля может вернуть путь с нулём перехода от исходного узла к самому себе.

ALL SHORTEST И ANY поиск по пути не поддерживается.

Размещение предикатов до или после выбора пути

Расположение предиката определяет, определяет ли условие подходящие пути или фильтрует пути после того, как префикс поиска пути выбрал их:

  • Инлайн WHERE в узоре узла или рёбер является частью паттерна. Это ограничивает, какие пути допустимы до ALL или ANY SHORTEST применяются.
  • Уровень WHERE оператора после полного MATCH шаблона называется постфильтром. Он фильтрует строки после того, как префикс поиска пути выбрал пути.
  • Последующий FILTER оператор также фильтрует строки после выбора пути.

Это различие особенно важно для ANY SHORTEST. В следующем шаблоне допускаются только knows рёбра, созданные в указанную дату или позже, когда запрос выбирает кратчайший путь:

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')
  -[connection:knows
    WHERE connection.creationDate >= ZONED_DATETIME('2020-01-01T00:00:00Z')]->{1,4}
  (dst:Person WHERE dst.firstName = 'Bob')
RETURN p

Перенос состояния края в постфильтр меняет значение. Запрос сначала выбирает кратчайший путь без этого условия. Затем он удаляет выбранный путь, если какое-либо ребро не выполняет условие; вместо этого он не выбирает более длинный путь:

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')
  -[connections:knows]->{1,4}
  (dst:Person WHERE dst.firstName = 'Bob')
FILTER ALL(connection IN connections
           WHERE connection.creationDate >= ZONED_DATETIME('2020-01-01T00:00:00Z'))
RETURN p

Это важно

Для некоторых ANY SHORTEST форм запроса Graph в настоящее время может применять условие на уровне MATCH ... WHERE оператора перед выбором пути. Пока это ограничение не будет устранено, используйте встроенные предикаты для допустимости пути и отдельный FILTER оператор для фильтрации после выбора. Дополнительные сведения см. в разделе "Текущие ограничения".

Использование шаблонов переменной длины

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

Ограниченные шаблоны переменной длины

Многие распространенные запросы графа требуют повторения одного и того же пограничного шаблона несколько раз. Вместо написания подробных шаблонов, таких как:

(:Person)-[:knows]->(:Person)-[:knows]->(:Person)-[:knows]->(:Person)

Вы можете использовать более краткий синтаксис переменной длины:

(:Person)-[:knows]->{3}(:Person)

Указывает {3} , что граничный -[:knows]-> шаблон должен повторяться ровно три раза.

Гибкие диапазоны повторений: Для повышения гибкости можно указать нижнюю границу, так и верхнюю границу для повторения:

(:Person)-[:knows]->{1, 3}(:Person)

Этот шаблон находит прямых друзей, друзей и друзей-друзей всех в одном запросе.

Замечание

Нижняя граница также может быть равна нулю. Совпадение с нулевым переходом не содержит рёбер и требует, чтобы оба шаблона узлов концевой точки совпадали с одним узлом.

Пример:

(p1:Person)-[:knows]->{0,1}(p2:Person)

Этот паттерн совпадает с каждым человеком как p1 и p2 с нулём прыжков, а также с связными парами при одном прыжке.

Если нижняя граница не указана в {,n}, по умолчанию нуля.

Комплексные композиции переменной длины: Паттерны переменной длины могут быть частью более крупных и сложных паттернов, как в следующем запросе:

MATCH (c1:Comment)<-[:likes]-(p1:Person)-[:knows]-(p2:Person)-[:likes]->(c2:Comment),
      (c1:Comment)<-[:replyOf]-{1,3}(m)-[:replyOf]->{1,3}(c2:Comment)
RETURN *
LIMIT 100

Паттерн находит пары комментариев, где знакомые люди ставят лайки разные комментарии, и сообщение m связывается с каждым комментарием цепочкой из одного-трёх replyOf рёбер.

Привязка переменных шаблоны граничных переменных длины

При привязке шаблона края переменной длины значение и тип переменной граничной переменной изменяются в зависимости от контекста ссылки. Понимание этого поведения имеет решающее значение для правильной обработки совпадений переменной длины:

Две степени ссылки:

  • Внутри шаблона переменной длины: пограничные переменные графа привязываются к каждому отдельному краю вдоль соответствующего пути (также называемой "однотонной степенью ссылки")
  • Вне шаблона переменной длины: пограничные переменные графа привязываются ко последовательности всех ребер вдоль соответствующего пути (также называется "степенью ссылки группы")

Пример демонстрации обоих контекстов:

MATCH (:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z")]->{1,3}()
RETURN e[0]
LIMIT 100

Оценка пограничной переменной e выполняется в двух контекстах:

  • MATCH В заявлении: Запрос находит цепочки друзей-друзей, где каждая дружба была создана с 2000 года. Во время сопоставления шаблонов предикат e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z") граничного шаблона вычисляется один раз для каждого края кандидата. В этом контексте e привязано к одному граничной ссылке.

  • В инструкцииRETURN: здесь e привязан список ссылочных значений edge (group) в порядке, который они происходят в соответствующей цепочке. Результатом e[0] является первое значение ссылки на ребра в каждой соответствующей цепочке.

Переменные ребер узора переменной длины в горизонтальной агрегации:

Реберные переменные, ограниченные сопоставлением узоров с переменной длиной, являются групповыми списками вне схемы переменной длины и, следовательно, могут использоваться в горизонтальной агрегации.

MATCH (a:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z")]->{1,3}(b)
RETURN a, b, size(e) AS num_edges
LIMIT 100

Для получения дополнительной информации см. раздел «Агрегированные функции».

Неподвязанные шаблоны переменной длины

Используйте неограниченный квантор, когда максимальная длина пути неизвестна:

-- Two or more edges
TRAIL (:Person)-[:knows]->{2,}(:Person)

Ярлыки и + указывают * на ноль или больше и одно или больше повторений:

-- Zero or more edges
ACYCLIC (:Person)-[:knows]->*(:Person)

-- One or more edges
SIMPLE (:Person)-[:knows]->+(:Person)

Неограниченный паттерн с комбинацией по умолчанию ALL WALK отвергается, потому что циклы могут создавать бесконечное количество совпадающих путей. Используйте TRAIL, SIMPLE, или ACYCLIC чтобы ограничить путь через уникальность ребра или узла. Эти режимы гарантируют завершение, но большой граф всё равно может создавать большое количество путей.

Это важно

Для пути, ограниченного неограниченным ANY SHORTEST WALK, единственными поддерживаемыми применениями являются PATH_LENGTH(path) и, наряду с ним, path IS NULL. Граф не материализует полный путь в такой форме. Используйте конечную верхнюю границу или укажите TRAIL, SIMPLE, или ACYCLIC чтобы вернуть или иным образом использовать этот путь.