Поделиться через


Руководство по языку GQL

Замечание

Эта функция сейчас доступна в общедоступной предварительной версии. Эта предварительная версия предоставляется без соглашения на уровне обслуживания и не рекомендуется для рабочих нагрузок. Некоторые функции могут не поддерживаться или их возможности могут быть ограничены. Для получения дополнительной информации см. Дополнительные условия использования для предварительных версий Microsoft Azure.

Язык запросов GQL Graph — это стандартизированный язык запросов ISO для баз данных графов. Он помогает выполнять запросы и эффективно работать с данными графа.

GQL разрабатывается той же рабочей группой по ISO, которая стандартизирует SQL, обеспечивая согласованность и строгость. Если вы знакомы с SQL, то найдёте много сходств в GQL (выражения, предикаты, типы) — это облегчает начало. Это руководство служит как новичкам, обучающим основы GQL, так и опытным пользователям, ищущим передовые методы и исчерпывающую справочную информацию.

Замечание

Официальный международный стандарт для GQL — ISO/IEC 39075 Information Technology — языки баз данных — GQL.

Предпосылки

Перед погружением в GQL следует ознакомиться с этими понятиями:

  • Базовое понимание баз данных — опыт работы с любой системой баз данных (например, реляционной (SQL), NoSQL или графовой системой) полезен
  • Основные понятия графа — понимание узлов, ребер и связей в подключенных данных
  • Основы запросов — знание основных концепций запросов, таких как фильтрация, сортировка и агрегирование

Рекомендуемый фон:

  • Опыт работы с языками SQL или openCypher облегчает изучение синтаксиса GQL (это корни GQL).
  • Знакомство с моделированием данных помогает с проектированием схемы графа
  • Понимание конкретного варианта использования данных графа

Что вам потребуется:

  • Доступ к Microsoft Fabric с возможностями графа
  • Примеры данных или готовность к работе с нашими примерами социальных сетей
  • Базовый текстовый редактор для написания запросов

Подсказка

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

Что делает GQL особенным

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

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

Допустим, вы хотите найти людей и их друзей (тех, кто друг друга знает), которые оба родились до 1999 года. Вот как GQL выражает это с помощью визуального графового паттерна:

MATCH (person:Person)-[:knows]-(friend:Person)
WHERE person.birthday < 19990101 
  AND friend.birthday < 19990101
RETURN person.firstName || ' ' || person.lastName AS person_name, 
       friend.firstName || ' ' || friend.lastName AS friend_name

Этот запрос находит друзей (людей, которые знают друг друга), которые родились до 1999 года. (person:Person)-[:knows]-(friend:Person) Шаблон визуально показывает структуру связей, которую вы ищете, так же как рисование схемы данных.

Основы GQL

Прежде чем изучить запросы, ознакомьтесь с этими основными понятиями, которые формируют основу GQL:

  • Графы хранят ваши данные в виде узлов (сущностей) и рёбер (отношений), каждый с метками и свойствами
  • Типы графов действуют как схемы, определяя, какие узлы и ребра могут существовать в графе
  • Ограничения — это дополнительные правила и ограничения, накладываемые типами графов на графы для обеспечения целостности данных
  • Запросы используют такие операторы, как MATCH, FILTERи RETURN для обработки данных и отображения результатов
  • Шаблоны описывают структуры графов, которые нужно найти с помощью интуитивно понятного визуального синтаксиса.
  • Выражения выполняют вычисления и сравнения данных, аналогичные выражениям SQL
  • Предикаты — это булевые выражения, используемые для фильтрации результатов внутри запросов
  • Типы значений определяют, какие типы значений можно обрабатывать и хранить

Общие сведения о данных графа

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

Узлы и края: стандартные блоки

В GQL вы работаете с графами свойств с метками. Граф состоит из двух типов элементов:

Узлы обычно представляют сущности (существительные) в вашей системе — такие как люди, организации, записи или продукты. Они независимые объекты, которые существуют в вашем домене. Узлы иногда называются вершинами.

Ребра представляют связи между сущностями ("глаголы") — как сущности подключаются и взаимодействуют. Например, люди знакомы друг с другом (:knows), организации, работающие в определённых регионах (:operates), или клиенты, которые приобрели товары (:purchased).
Ребра иногда называются связями.

Каждый элемент графа имеет следующие характеристики:

  • Внутренний идентификатор, который однозначно идентифицирует его
  • Одна или несколько меток — описательные имена, например Person или knows. В Microsoft Fabric рёбра графа всегда имеют ровно одну метку.
  • Свойства — пары имя-значение, которые хранят данные об элементе (например firstName: "Alice" , или birthday: "19730108").

Структура графов

Каждый край подключается ровно к двум узлам: источнику и назначению. Это соединение создает структуру графа и показывает, как сущности связаны друг с другом. Направление ребер имеет значение — Person кто follows другой Person создает направленную связь.

Замечание

В Microsoft Fabric в Microsoft Fabric в настоящее время не поддерживает неориентированные рёбра.

Графы свойств, поддерживаемые в Microsoft Fabric, всегда корректно сформированы, то есть каждое ребро соединяет два допустимых узла. Если в графе отображается ребра, обе конечные точки существуют в одном графе.

Модели графа и типы графов

Структура графа в Microsoft Fabric описывается своей моделью графа, которая действует как схема базы данных для домена приложения. Модели Графа определяют:

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

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

Замечание

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

Практический пример: социальная сеть

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

Схема социальной сети.

Замечание

Социальная сеть является примером, производным от SNB LDBC (LDBC Social Network Benchmark), опубликованного GDC (Graph Data Council). Дополнительные сведения см. в статье "Тест социальной сети LDBC".

Сущности социальной сети

Наша социальная сеть включает следующие основные типы узлов, представляющих сущности домена:

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

Места образуют географическую иерархию:

  • Города , такие как "Нью-йорк" или "Лондон"
  • Страны или регионы , такие как "Соединенные Штаты" или "Соединенное Королевство"
  • Континенты , такие как "Северная Америка" или "Европа"

Организации , где люди тратят время:

  • Университеты , где люди учатся
  • Компании , где работают люди

Содержимое и обсуждения:

  • Форумы с заголовками, содержащими записи
  • Записи с содержимым, языком и необязательными изображениями
  • Комментарии , которые отвечают на сообщения или другие комментарии
  • Теги , которые классифицируют содержимое и представляют интересы

Как все подключается

Подключения между сущностями делают сеть интересной:

  • Люди знакомы друг с другом (дружба, :knows)
  • Люди работают в компаниях (:workAt) или учатся в университетах (:studyAt)
  • Люди создают посты и комментарии (:hasCreator)
  • Люди любят посты и комментарии (:likes)
  • Посты, форумы, комментарии могут иметь теги (:hasTag)
  • Люди интересуются определёнными тегами (:hasInterest)
  • Форумы содержат посты (:containerOf) и участники (:hasMember) и модераторы (:hasModerator)

Границы графа представляют связи домена. Эта многофункциональная сеть создает множество возможностей для интересных запросов и анализа.

Первые запросы GQL

Теперь, когда вы понимаете основы графа, давайте посмотрим, как запрашивать данные графа с помощью GQL. Эти примеры создаются из простого в сложный, показывающий, как подход GQL делает графовые запросы интуитивно понятными и мощными.

Начните просто: найти всех людей

Начнём с самого базового запроса — найдём имена (имя, фамилия) всех людей (:Personлюдей) на графике.

MATCH (p:Person)
RETURN p.firstName, p.lastName

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

  1. MATCH находит все узлы, помеченные Person
  2. RETURN отображает свои имена и фамилии

Добавление фильтрации: поиск определенных пользователей

Теперь найдём людей с определёнными чертами, в данном случае — всех по имени Алиса, и покажем их имена и даты рождения.

MATCH (p:Person)
FILTER p.firstName = 'Annemarie'
RETURN p.firstName, p.lastName, p.birthday

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

  1. MATCH находит все узлы (p), помеченные как Person
  2. FILTER узлы (p), имя которых — Алиса
  3. RETURN показывает имя, фамилию и дату рождения

Базовая структура запросов

Базовые запросы GQL соответствуют согласованному шаблону: последовательность операторов, которые работают вместе для поиска, фильтрации и возврата данных. Большинство запросов начинаются с MATCH поиска закономерностей в графе и заканчиваются с RETURN указанием результата.

Вот простой запрос, который находит пары знакомых людей с одним днём рождения, а затем возвращает общее количество этих пар друзей.

MATCH (n:Person)-[:knows]-(m:Person)
FILTER n.birthday = m.birthday
RETURN count(*) AS same_age_friends

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

  1. MATCH находит все пары Person узлов, которые знают друг друга
  2. FILTER держит только пары, где оба человека имеют один день рождения
  3. RETURN подсчитывает, сколько таких пар друзей существуют

Подсказка

Фильтрация также может выполняться непосредственно в рамках шаблона путем добавления WHERE предложения. Например, MATCH (n:Person WHERE n.age > 23) будет соответствовать Person только узлам, свойство которых age больше 23.

Замечание

GQL поддерживает примечания в стиле // C, примечания строки в стиле -- SQL и примечания в стиле /* */ C.

Распространённые утверждения

  • MATCH: Определяет шаблон графа для поиска — здесь вы определяете структуру интересующих вас данных.
  • LET: Назначает новые переменные или вычисленные значения на основе сопоставленных данных — добавляет производные столбцы к результату.
  • FILTER: Сужает круг результатов, применяя условия — удаляет строки, не соответствующие критериям.
  • ORDER BY: Сортирует отфильтрованные данные — помогает организовать результат по одному или нескольким полям.
  • OFFSET и LIMIT: Ограничить количество возвращаемых строк — полезно для пагинации или запросов с верхними k.
  • RETURN: Определяет конечный результат — определяет, какие данные должны быть включены в набор результатов, и выполняет агрегацию.

Совместная работа инструкций

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

Основные моменты:

  • Операторы фактически выполняются последовательно.
  • Каждое утверждение преобразует данные и передаёт их следующему.
  • Это создаёт чёткий, предсказуемый поток данных, упрощающий сложные запросы.

Это важно

Внутри процесс выполнения операторов можно переупорядочивать, а отдельные операторы выполнять параллельно Microsoft Fabric для максимизации производительности. Однако это не повлияет на корректность результатов.

Пример

Следующий запрос в GQL находит первых 10 человек, работающих в компаниях с «Air» в названии, сортирует их по полному имени и возвращает их полное имя вместе с названием их компаний.

-- Data flows: Match → Let → Filter → Order → Limit → Return
MATCH (p:Person)-[:workAt]->(c:Company)           -- Input: unit table, Output: (p, c) table
LET fullName = p.firstName || ' ' || p.lastName   -- Input: (p, c) table, Output: (p, c, fullName) table
FILTER c.name CONTAINS 'Air'                      -- Input: (p, c, fullName) table, Output: filtered table
ORDER BY fullName                                 -- Input: filtered table, Output: sorted table
LIMIT 10                                          -- Input: sorted table, Output: top 10 rows table
RETURN fullName, c.name AS companyName            -- Input: top 10 rows table
                                                  -- Output: projected (fullName, companyName) result table

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

  1. MATCH находит людей, работающих в компаниях с «Air» в названии
  2. LET Создаёт полные имена, объединяя фамилии и фамилии
  3. FILTER удерживается только сотрудники Contoso
  4. ORDER BY сортировка по полному имени
  5. LIMIT получает первые 10 результатов
  6. RETURN Возвращает названия и местоположение компаний

Переменные подключают данные

Переменные (например p, cи fullName в предыдущих примерах) содержат данные между операторами. При повторном использовании имени переменной GQL автоматически гарантирует, что он ссылается на те же данные, создавая мощные условия соединения. Переменные иногда называются переменными привязки.

Переменные можно классифицировать по-разному:

По источнику привязки:

Типы переменных шаблонов:

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

По эталонной степени:

  • Одноэлементные переменные — привязка к отдельным значениям ссылок на элемент из шаблонов
  • Групповые переменные — привязка к спискам ссылочных значений элементов из шаблонов переменной длины (см. дополнительные методы агрегирования)

Результаты выполнения и результаты

При выполнении запроса возвращается результат выполнения , состоящий из следующих элементов:

  • Таблица результатов (необязательно) с данными из инструкции RETURN .
  • Сведения о состоянии , показывающие, выполнен ли запрос успешно или нет.

Таблицы результатов

Таблица результатов ( если она присутствует) является фактическим результатом выполнения запроса.

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

Замечание

В случае сбоя выполнения таблица результатов не включается в результат выполнения.

Сведения о состоянии

Во время выполнения запроса обнаруживаются различные важные условия (например, ошибки или предупреждения). Каждое такое условие записывается объектом состояния в сведениях о состоянии результата выполнения.

Сведения о состоянии состоят из основного объекта состояния и (возможно, пустого) списка дополнительных объектов состояния. Основной объект состояния всегда присутствует и указывает, успешно ли выполнено выполнение запроса или завершилось сбоем.

Каждый объект состояния содержит 5-значный код состояния (gQLSTATUS), который определяет записанное условие, а также сообщение, описывающее его.

Коды состояния успешного выполнения:

GQLSTATUS Message Когда
00000 примечание. Успешное завершение Успешное выполнение по крайней мере одной строки
00001 примечание. Успешное завершение — опущен результат Успех без таблицы (в настоящее время не используется)
02000 примечание. Данные отсутствуют Успех с нулевыми строками

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

Это важно

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

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

Основные понятия и инструкции

В этом разделе рассматриваются основные стандартные блоки, необходимые для записи эффективных запросов GQL. Каждая концепция строится на основе практических навыков написания запросов.

Шаблоны графа: поиск структуры

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

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

Начните с базовых шаблонов связей:

-- Find direct friendships
(p:Person)-[:knows]->(f:Person)

-- Find people working at any company
(p:Person)-[:workAt]->(c:Company)

-- Find cities in any country/region
(ci:City)-[:isPartOf]->(co:Country)  

Шаблоны с определенными данными:

-- Find who works at Microsoft specifically
(p:Person)-[:workAt]->(c:Company)
WHERE p.firstName = 'Annemarie'

-- Find friends who are both young
(p:Person)-[:knows]->(f:Person)  
WHERE p.birthday > 19950101 AND f.birthday > 19950101

Выражения меток для гибкого выбора сущностей:

(:Person|Company)-[:isLocatedIn]->(p:City|Country)  -- OR with |
(:Place&City)                                       -- AND with &  
(:Person&!Company)                                  -- NOT with !

Замечание

Модели графов с несколькими метками элементов пока не поддерживаются (известная проблема).

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

Повторное использование переменной создает мощные соединения:

-- Find coworkers: people who work at the same company
(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c)

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

Это важно

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

Фильтрация на уровне шаблона с помощью WHERE:

-- Filter during pattern matching (more efficient)
(p:Person WHERE p.birthday < 19940101)-[:workAt]->(c:Company WHERE c.id > 1000)

-- Filter edges during matching  
(p:Person)-[w:workAt WHERE w.workFrom >= 2000]->(c:Company)

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

(:Person)-[:knows]->{1,3}(:Person)  -- Friends up to 3 degrees away

Шаблоны TRAIL для обхода без циклов:

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

-- Find paths without visiting the same :knows edge twice
MATCH TRAIL (src:Person)-[:knows]->{1,4}(dst:Person)
WHERE src.firstName = 'Alice' AND dst.firstName = 'Bob'
RETURN count(*) AS num_connections
-- Find acyclic paths in social networks
MATCH TRAIL (p:Person)-[e:knows]->{,3}(celebrity:Person)
RETURN 
  p.firstName || ' ' || p.lastName AS person_name, 
  celebrity.firstName || ' ' || celebrity.lastName AS celebrity_name, 
  count(e) AS distance
LIMIT 1000

Привязка ребра переменной длины:

В шаблонах переменной длины пограничные переменные собирают разные сведения на основе контекста:

-- Edge variable 'e' binds to a single edge for each result row
MATCH (p:Person)-[e:knows]->(friend:Person)
RETURN p.firstName, e.creationDate, friend.firstName  -- e refers to one specific relationship
LIMIT 1000

-- Edge variable 'e' binds to a group list of all edges in the path
MATCH (p:Person)-[e:knows]->{2,4}(friend:Person)  
RETURN 
  p.firstName || ' ' || p.lastName AS person_name, 
  friend.firstName || ' ' || friend.lastName AS friend_name, 
  -- e is a list
  size(e) AS num_edges
LIMIT 1000

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

Сложные шаблоны с несколькими связями:

MATCH (p:Person), (p)-[:workAt]->(c:Company), (p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, p.lastName, c.name AS company_name, city.name AS city_name
LIMIT 1000

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

Основные операторы

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

заявление MATCH

Синтаксис

MATCH <graph pattern>, <graph pattern>, ... [ WHERE <predicate> ]

Оператор MATCH принимает входные данные и находит шаблоны графов, присоединяя входные переменные с переменными шаблона и выводя все соответствующие сочетания.

Входные и выходные переменные:

-- Input: unit table (no columns, one row)
-- Pattern variables: p, c  
-- Output: table with (p, c) columns for each person-company match
MATCH (p:Person)-[:workAt]->(c:Company)

Фильтрация на уровне инструкций с помощью WHERE:

-- Filter pattern matches
MATCH (p:Person)-[:workAt]->(c:Company) WHERE p.lastName = c.name

Все совпадения можно отфильтровать после фильтрации, WHEREизбегая отдельной FILTER инструкции.

Присоединение к входным переменным:

Если MATCH это не первая инструкция, она присоединяет входные данные с совпадениями шаблонов:

...
-- Input: table with 'targetCompany' column
-- Implicit join: targetCompany (equality join)
-- Output: table with (targetCompany, p, r) columns
MATCH (p:Person)-[r:workAt]->(targetCompany)

Это важно

Graph в Microsoft Fabric пока не поддерживает произвольный состав инструкций. См. статью о текущих ограничениях.

Поведение соединения ключей:

Как MATCH обрабатывает присоединение данных:

  • Равенство переменных: входные переменные объединяются с переменными шаблона с использованием сопоставления равенства
  • Внутреннее соединение: входные строки без совпадений шаблонов удаляются (нет соединений влево или вправо)
  • Порядок фильтрации: фильтры уровня WHERE инструкций после завершения сопоставления шаблонов
  • Подключение к шаблону: несколько шаблонов должны совместно использовать по крайней мере одну переменную для надлежащего соединения.
  • Производительность. Общие переменные создают эффективные ограничения соединения

Это важно

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

Для нескольких шаблонов требуются общие переменные:

-- Shared variable 'p' joins the two patterns
-- Output: people with both workplace and residence data
MATCH (p:Person)-[:workAt]->(c:Company), 
      (p)-[:isLocatedIn]->(city:City)

заявление LET

Синтаксис

LET <variable> = <expression>, <variable> = <expression>, ...

Оператор LET создает вычисляемые переменные и включает преобразование данных в конвейере запросов.

Базовое создание переменной:

MATCH (p:Person)
LET fullName = p.firstName || ' ' || p.lastName
RETURN *
LIMIT 1000

Сложные вычисления:

MATCH (p:Person)
LET adjustedAge = 2000 - (p.birthday / 10000),
    fullProfile = p.firstName || ' ' || p.lastName || ' (' || p.gender || ')'
RETURN *
LIMIT 1000

Ключевые действия:

  • Выражения вычисляются для каждой входной строки
  • Результаты становятся новыми столбцами в выходной таблице
  • Переменные могут ссылаться только на существующие переменные из предыдущих инструкций
  • Несколько назначений в одном LET вычисляются параллельно (без перекрестных ссылок)

заявление FILTER

Синтаксис

FILTER [ WHERE ] <predicate>

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

Базовая фильтрация:

MATCH (p:Person)
FILTER p.birthday < 19980101 AND p.gender = 'female'
RETURN *

Сложные логические условия:

MATCH (p:Person)
FILTER (p.gender = 'male' AND p.birthday < 19940101) 
  OR (p.gender = 'female' AND p.birthday < 19990101)
  OR p.browserUsed = 'Edge'
RETURN *

Шаблоны фильтрации с поддержкой NULL:

Используйте эти шаблоны для безопасной обработки значений NULL:

  • Проверка значений: p.firstName IS NOT NULL имеет имя
  • Проверка данных: p.id > 0 — допустимый идентификатор
  • Обработка отсутствующих данных: NOT coalesce(p.locationIP, '127.0.0.1') STARTS WITH '127.0.0' не подключались из локальной сети.
  • Объединение условий: использование AND/OR явных проверок NULL для сложной логики

Caution

Помните, что условия, включающие возвращаемые UNKNOWNзначения NULL, которые фильтруют эти строки. Используйте явные IS NULL проверки, когда требуется логика, включаемая в значение NULL.

заявление ORDER BY

Синтаксис

ORDER BY <expression> [ ASC | DESC ], <expression> [ ASC | DESC ], ...

Многоуровневая сортировка с вычисляемых выражений:

MATCH (p:Person)
RETURN *
ORDER BY p.firstName DESC,               -- Primary: by first name (Z-A)
         p.birthday ASC,                 -- Secondary: by age (oldest first)
         p.id DESC                       -- Tertiary: by ID (highest first)

Обработка NULL в сортировке:

ORDER BY coalesce(p.gender, 'not specified') DESC -- Treat NULL as 'not specified'

Сведения о поведении сортировки:

Общие сведения о работе ORDER BY :

  • Оценка выражений: выражения вычисляются для каждой строки, а затем результаты определяют порядок строк.
  • Несколько ключей сортировки: создание иерархического упорядочения (первичного, вторичного, третьего и т. д.)
  • Обработка NULL: NULL всегда рассматривается как наименьшее значение в сравнениях
  • Порядок по умолчанию: ASC (по возрастанию) по умолчанию DESC (убывание) должно быть указано явным образом.
  • Вычисленная сортировка: вы можете сортировать по вычисляемым значениям, а не только хранимым свойствам.

Caution

Порядок сортировки, установленный ORDER BY только для следующей инструкции, отображается только в следующей инструкции. Следовательно, ORDER BY за ним RETURN * не производится упорядоченный результат.

Сравнивать:

MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
ORDER BY r.creationDate DESC
/* intermediary result _IS_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
/* final result _IS_ _NOT_ guaranteed to be ordered here  */

с:

MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
/* intermediary result _IS_ _NOT_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
ORDER BY r.creationDate DESC
/* final result _IS_ guaranteed to be ordered here              */

Это имеет немедленные последствия для запросов Top-k: LIMIT всегда следует следовать ORDER BY инструкции, которая установила предполагаемый порядок сортировки.

Выражения OFFSET и LIMIT

Синтаксис

  OFFSET <offset> [ LIMIT <limit> ]
| LIMIT <limit>

Распространенные шаблоны:

-- Basic top-N query
MATCH (p:Person)
RETURN *
ORDER BY p.id DESC
LIMIT 10                                 -- Top 10 by ID

Это важно

Для прогнозируемых результатов разбиения на страницы всегда следует использовать ORDER BY до OFFSET и LIMIT обеспечить согласованное упорядочивание строк в запросах.

RETURN: базовая проекция результатов

Синтаксис

RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
[ ORDER BY <expression> [ ASC | DESC ], <expression> [ ASC | DESC ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]

Оператор RETURN создает окончательные выходные данные запроса, указав, какие данные отображаются в таблице результатов.

Базовые выходные данные:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name, 
       p.birthday, 
       c.name

Использование псевдонимов для ясности:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName AS first_name, 
       p.lastName AS last_name,
       c.name AS company_name

Объединение с сортировкой и top-k:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name, 
       p.birthday AS birth_year, 
       c.name AS company
ORDER BY birth_year ASC
LIMIT 10

Повторная обработка с помощью DISTINCT:

-- Remove duplicate combinations
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN DISTINCT p.gender, p.browserUsed, p.birthday AS birth_year
ORDER BY p.gender, p.browserUsed, birth_year

Объединение с агрегированием:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN count(DISTINCT p) AS employee_count

RETURN с GROUP BY: сгруппированная проекция результатов

Синтаксис

RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
GROUP BY <variable>, <variable>, ...
[ ORDER BY <expression> [ ASC | DESC ], <expression> [ ASC | DESC ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]

Используется GROUP BY для группировки строк по общим значениям и вычислительным агрегатным функциям в каждой группе.

Базовая группировка с агрегированием:

MATCH (p:Person)-[:workAt]->(c:Company)
LET companyName = c.name
RETURN companyName, 
       count(*) AS employeeCount,
       avg(p.birthday) AS avg_birth_year
GROUP BY companyName
ORDER BY employeeCount DESC

Группирование нескольких столбцов:

MATCH (p:Person)
LET gender = p.gender
LET browser = p.browserUsed
RETURN gender,
       browser,
       count(*) AS person_count,
       avg(p.birthday) AS avg_birth_year,
       min(p.creationDate) AS first_joined,
       max(p.id) AS highest_id
GROUP BY gender, browser
ORDER BY avg_birth_year DESC
LIMIT 10

Замечание

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

Типы данных: работа со значениями

GQL поддерживает расширенные типы данных для хранения и управления различными типами информации в графе.

Базовые типы значений:

  • Числа: INT64, UINT64DOUBLE для вычислений и измерений
  • Текст: STRING для имен, описаний и текстовых данных
  • Логика: BOOL с тремя значениями: TRUE, FALSE и UNKNOWN (для обработки null)
  • Время: ZONED DATETIME метки времени с сведениями о часовом поясе
  • Коллекции: LIST<T> для нескольких значений одного типа T, PATH для результатов обхода графов
  • Элементы графа: NODE и EDGE для ссылок на данные графа

Это важно

Некоторые типы значений не поддерживаются как типы стоимости недвижимости. В частности, все значения, связанные с эталонными значениями элементов графа, не могут использоваться как значения свойств (например, списки узлов или путей).

Примеры литералы:

42                                     -- Integer literal
"Hello, graph!"                        -- String  literal
TRUE                                   -- Boolean literal
ZONED_DATETIME('2024-01-15T10:30:00Z') -- DateTime with timezone literakl
[1, 2, 3]                              -- Literal list of integers

Критически важные шаблоны обработки null:

-- Equality predicates with NULL always returns UNKNOWN
5 = NULL                              -- Evaluates to UNKNOWN (not FALSE!)
NULL = NULL                           -- Evaluates to UNKNOWN (not TRUE!)

-- Use IS NULL predicates for explicit null testing
p.nickname IS NULL                    -- Evaluates to TRUE if nickname is null
p.nickname IS NOT NULL                -- Evaluates to TRUE if nickname has a value

-- Use the COALESCE function for null-safe value selection
coalesce(p.nickname, p.firstName, '???')  -- Evaluates to first non-null value

Три значения логики:

-- In FILTER statements, only TRUE values pass through
FILTER p.birthday > 0        -- Removes rows where birthday is null or missing or zero

-- It's important to understand that NOT UNKNOWN = UNKNOWN
FILTER NOT (p.birthday > 0)  -- Removes rows where birthday is null or missing or positive

-- Use explicit null handling for inclusive filtering
FILTER p.birthday < 19980101 OR p.birthday IS NULL -- Includes null birthdays

Caution

Трехзначная логика означает NULL = NULL возврат UNKNOWN, а не TRUE. Это поведение влияет на фильтрацию и соединения. Всегда используется IS NULL для пустых тестов.

Выражения: преобразование и анализ данных

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

Распространенные типы выражений:

p.birthday < 19980101   -- Birth year comparison  
p.firstName || ' ' || p.lastName               -- String concatenation
count(*)                                       -- Aggregation
p.firstName IN ['Alice', 'Bob']                -- List membership
coalesce(p.firstName, p.lastName)              -- Null handling

Сложная композиция предиката:

-- Combine conditions with proper precedence
FILTER (p.birthday > 19560101 AND p.birthday < 20061231) 
  AND ((p.gender IN ['male', 'female']) OR (p.browserUsed IS NOT NULL))

-- Use parentheses for clarity and correctness
FILTER p.gender = 'female' AND (p.firstName STARTS WITH 'A' OR p.id > 1000)

Сопоставление шаблонов строк:

-- Pattern matching with different operators
p.locationIP CONTAINS '192.168'      -- Substring search
p.firstName STARTS WITH 'John'       -- Prefix matching  
p.lastName ENDS WITH 'son'           -- Suffix matching

-- Case-insensitive operations
upper(p.firstName) = 'ALICE'         -- Convert to uppercase for comparison

Встроенные функции по категориям:

GQL предоставляет следующие категории функций для различных потребностей в обработке данных:

  • Статистические функции: count(), , sum()avg()min(), max() для суммирования данных
  • Строковые функции: char_length(), , upper()lower()trim()для обработки текста
  • Функции графа: nodes(), edges()labels()для анализа структур графа
  • Общие функции: coalesce() для обработки значений NULL корректно

Приоритет оператора для сложных выражений:

  1. Доступ к свойствам (.)
  2. Умножение и деление (*, /)
  3. Добавление и вычитание (+, -)
  4. Сравнение (=, , <><, >, <=) >=
  5. Логическое отрицание (NOT)
  6. Логическое сочетание (AND)
  7. Логическое дисъюнкция (OR)

В приведённом выше списке оператор с меньшим числом «связывает всё плотнее», чем оператор с большим числом. Пример: NOT n.prop OR m.prop есть (NOT n.prop) OR m.prop , но не 'NOT (n.prop ИЛИ m.prop)

Подсказка

Используйте скобки для явного приоритета. Сложные выражения проще читать и отлаживать при очистке группировки.

Расширенные методы запросов

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

Сложная композиция с несколькими операторами

Это важно

Graph в Microsoft Fabric пока не поддерживает произвольный состав инструкций. См. статью о текущих ограничениях.

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

Прогрессирование шаблонов на нескольких шагах:

-- Build complex analysis step by step
MATCH (company:Company)<-[:workAt]-(employee:Person)
LET companyName = company.name
MATCH (employee)-[:isLocatedIn]->(city:City)
FILTER employee.birthday < 19850101
LET cityName = city.name
RETURN companyName, cityName, avg(employee.birthday) AS avgBirthday, count(employee) AS employeeCount
GROUP BY companyName, cityName
ORDER BY avgBirthday DESC

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

Использование горизонтальной агрегирования:

-- Find people and their minimum distance to people working at Microsoft
MATCH TRAIL (p:Person)-[e:knows]->{,5}(:Person)-[:workAt]->(:Company { name: 'Microsoft'})
LET p_name = p.lastName || ', ' || p.firstName
RETURN p_name, min(count(e)) AS minDistance 
GROUP BY p_name
ORDER BY minDistance DESC

Замечание

Этот запрос пока не поддерживается (известная проблема).

Область переменных и расширенный элемент управления потоками

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

Привязка переменных и шаблоны области:

-- Variables flow forward through subsequent statements 
MATCH (p:Person)                                    -- Bind p 
LET fullName = p.firstName || ' ' || p.lastName     -- Bind concatenation of p.firstName and p.lastName as fullNume
FILTER fullName CONTAINS 'Smith'                    -- Filter for fullNames with “Smith” substring (p is still bound)
RETURN p.id, fullName                               -- Only return p.id and fullName (p is dropped from scope) 

Переменная повторно используется для соединений между операторами:

-- Multi-statement joins using variable reuse
MATCH (p:Person)-[:workAt]->(:Company)          -- Find people with jobs
MATCH (p)-[:isLocatedIn]->(:City)               -- Same p: people with both job and residence
MATCH (p)-[:knows]->(friend:Person)             -- Same p: their social connections
RETURN *

Критические правила и ограничения области:

-- ✅ Backward references work
MATCH (p:Person)
LET adult = p.birthday < 20061231  -- Can reference p from previous statement
RETURN *

-- ❌ Forward references don't work  
LET adult = p.birthday < 20061231  -- Error: p not yet defined
MATCH (p:Person)
RETURN *

-- ❌ Variables in same LET statement can't reference each other
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName,
    greeting = 'Hello, ' || name     -- Error: name not visible yet
RETURN *

-- ✅ Use separate statements for dependent variables
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName
LET greeting = 'Hello, ' || name     -- Works: name now available
RETURN *

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

-- Variables remain visible until overridden or query ends
MATCH (p:Person)                     -- p available from here
LET gender = p.gender                -- gender available from here  
MATCH (p)-[:knows]->(e:Person)       -- p still refers to original person
                                     -- e is new variable for managed employee
RETURN p.firstName AS manager, e.firstName AS friend, gender

Caution

Переменные в одной инструкции не могут ссылаться друг на друга (за исключением шаблонов графов). Используйте отдельные инструкции для создания зависимых переменных.

Расширенные методы агрегирования

GQL поддерживает два разных типа агрегирования для анализа данных между группами и коллекциями: вертикальное агрегирование с GROUP BY использованием и горизонтальной агрегированием по шаблонам переменной длины.

Вертикальное агрегирование с помощью GROUP BY

Вертикальная агрегирование (покрываемая RETURNGROUP BY) группирует строки по общим значениям и вычисляет агрегаты в каждой группе:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN c.name AS companyName, 
       count(*) AS employee_count, 
       avg(p.birthday) AS avg_birth_year
GROUP BY companyName

Этот подход создает одну строку результатов для каждой компании, агрегируя всех сотрудников в каждой группе.

Горизонтальное агрегирование с переменными списка групп

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

-- Group list variable 'edges' enables horizontal aggregation
MATCH (p:Person)-[edges:knows]->{2,4}(friend:Person)
RETURN p.firstName || ' ' || p.lastName AS person_name, 
       friend.firstName || ' ' || friend.lastName AS friend_name,
       size(edges) AS degrees_of_separation,
       avg(edges.creationDate) AS avg_connection_age,
       min(edges.creationDate) AS oldest_connection

Замечание

Этот запрос пока не поддерживается (известная проблема).

Основные различия:

  • Вертикальное агрегирование суммирует данные по строкам или — группирует строки и суммирует между строками в каждой группе.
  • Горизонтальное агрегирование суммирует элементы в отдельных пограничных коллекциях
  • Переменные списка групп приходят только из шаблонов ребер переменной длины

Контексты привязки границ переменной длины

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

Во время сопоставления шаблонов (одноэлементный контекст):

-- Edge variable 'e' refers to each individual edge during filtering
MATCH (p:Person)-[e:knows WHERE e.creationDate > zoned_datetime('2000-01-01T00:00:00Z')]->{2,4}(friend:Person)
-- 'e' is evaluated for each edge in the path during matching
RETURN *

В выражениях результатов (контекст группы):

-- Edge variable 'edges' becomes a list of all qualifying edges
MATCH (p:Person)-[e:knows]->{2,4}(friend:Person)
RETURN size(e) AS num_edges,                    -- Number of edges in path
       e[0].creationDate AS first_edge,         -- First edge in path
       avg(e.creationDate) AS avg_age           -- Horizontal aggregation

Замечание

Этот запрос пока не поддерживается (известная проблема).

Объединение вертикальной и горизонтальной агрегирования

Оба типа агрегирования можно объединить в сложных шаблонах анализа:

-- Find average connection age by city pairs
MATCH (p1:Person)-[:isLocatedIn]->(c1:City)
MATCH (p2:Person)-[:isLocatedIn]->(c2:City)
MATCH (p1)-[e:knows]->{1,3}(p2)
RETURN c1.name AS city1,
       c2.name AS city2,
       count(*) AS connection_paths,                  -- Vertical: count paths per city pair
       avg(size(e)) AS avg_degrees,                   -- Horizontal then vertical: path lengths
       avg(avg(e.creationDate)) AS avg_connection_age -- Horizontal then vertical: connection ages
GROUP BY city1, city2

Замечание

Этот запрос пока не поддерживается (известная проблема).

Подсказка

Горизонтальное агрегирование всегда имеет приоритет над вертикальной агрегированием. Чтобы преобразовать список групп в обычный список, используйте collect_list(edges).

Замечание

Подробные справочные материалы по агрегатной функции см. в разделе "Выражения и функции GQL".

Стратегии обработки ошибок

Общие сведения о шаблонах ошибок помогают создавать надежные запросы.

Обработка отсутствующих данных корректно:

MATCH (p:Person)
-- Use COALESCE for missing properties
LET displayName = coalesce(p.firstName, p.lastName, 'Unknown')
LET contact = coalesce(p.locationIP, p.browserUsed, 'No info')
RETURN *

Используйте явные проверки NULL:

MATCH (p:Person)
-- Be explicit about null handling
FILTER p.id IS NOT NULL AND p.id > 0
-- Instead of just: FILTER p.id > 0
RETURN *

Дополнительные сведения

Коды GQLSTATUS

Как описано в разделе о результатах запроса, GQL сообщает подробные сведения о состоянии, связанные с успешной или потенциальной ошибкой выполнения. Дополнительные сведения см. в справочнике по кодам состояния GQL для полного списка.

Зарезервированные слова

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

Если вам нужно использовать зарезервированные слова в качестве идентификаторов, побежите их с помощью обратных выражений: `match`, . `return`

Чтобы избежать экранирования зарезервированных слов, используйте это соглашение об именовании:

  • Для идентификаторов с одним словом добавьте символ подчеркивания: :Product_
  • Для идентификаторов с несколькими словами используйте верблюдьи регистр или PascalCase: :MyEntity, :hasAttributetextColor

Дальнейшие шаги

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

Продолжить создание навыков GQL

Для начинающих:

Для опытных пользователей:

Справочные материалы

Следите за этими ссылками для быстрого поиска:

Обзор Microsoft Fabric

Узнайте о платформе:

Сообщество

  • Предоставление общего доступа к отзыву . Справка по улучшению документации и инструментов
  • Присоединение сообщества — подключение к другим специалистам по базам данных graph
  • Оставайтесь обновленными . Следуйте объявлениям Microsoft Fabric для новых функций

Подсказка

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

Дополнительные сведения о ключевых разделах:

Краткие ссылки:

Graph в Microsoft Fabric: