Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Фильтрация сужает результаты до строк, которые имеют значение. Агрегирование преобразует эти строки в подсчеты, итоги и средние значения. В этой статье показано, как применять оба метода в запросах GQL к графу в Microsoft Fabric.
В примерах используется пример набора данных социальной сети. Описание процесса выполнения запросов и инструкций от начала до конца см. в руководстве по языку GQL.
Используйте эту статью для фильтрации строк и шаблонов, сгруппированной и несгруппированной агрегации, фильтров для агрегатных функций и условной маршрутизации. Для построения многошаговых шаблонов и выбора путей см. раздел Создание запросов с шаблонами графов. Готовые к адаптации бизнес-задачи см. в разделе Написание типовых GQL-запросов.
Необходимые условия
- Графовый элемент, построенный из примера социальных сетей с типами узлов, рёберными типами и свойствами, описанными в примере схемы социальной сети.
- Знакомство с основными
MATCHиRETURNзапросами. См. руководство по языку GQL.
Фильтрация строк с помощью FILTER
Используется FILTER для хранения только строк, удовлетворяющих условию. Поместите FILTER после MATCH, чтобы сузить количество соответствующих результатов.
Следующий запрос возвращает всех женщин с их именем и днем рождения:
MATCH (p:Person)
FILTER p.gender = 'female'
RETURN p.firstName, p.lastName, p.birthday
Объедините несколько условий с AND и OR. Например, следующий запрос возвращает имена всех женщин, родившихся до 1990 года:
MATCH (p:Person)
FILTER p.gender = 'female' AND p.birthday < 19900101
RETURN p.firstName, p.lastName
Tip
Используйте встроенное WHERE предложение, когда условие определяет, какой узел или ребро может участвовать в матче. Используйте FILTER, когда условие применяется к строке, созданной более ранней инструкцией. Расположение предикатов может изменять результаты поиска кратчайшего пути; см. Размещайте предикаты до или после выбора пути.
Фильтрация во время сопоставления шаблонов
Встроенные WHERE предложения внутри MATCH шаблона ограничивают, какие узлы и рёбра подходят для совпадения. Оптимизатор запросов может применять эквивалентные предикаты при сканировании, поэтому встроенный синтаксис не является по своей сути быстрее, чем отдельный FILTER. Выберите форму, которая выражает задуманную семантику.
Например, чтобы найти людей, родившихся до 1994 года, и компанию, в которой они работают, ограничивая результаты компаниями, название которых начинается на "A":
MATCH (p:Person WHERE p.birthday < 19940101)-[:workAt]->(c:Company WHERE c.name STARTS WITH 'A')
RETURN p.firstName, p.lastName, c.name
Фильтруйте граничные свойства таким же образом. Например, чтобы выбрать только тех, кто начал работать в компании в 2000 году или позднее.
MATCH (p:Person)-[w:workAt WHERE w.workFrom >= 2000]->(c:Company)
RETURN p.firstName, p.lastName, c.name, w.workFrom
Для получения дополнительной информации о выборе между встроенной и послематчевой фильтрацией см. Оптимизировать производительность запросов GQL.
Обработка значений NULL в фильтрах
GQL использует трехзначную логику: предикаты оцениваются как TRUE, FALSEили UNKNOWN. Если значение свойства равно NULL, сравнения возвращаются UNKNOWN.
FILTER трактует UNKNOWN как не соответствующий, поэтому строка исключается.
Используйте IS NULL и IS NOT NULL проверьте значения NULL явным образом:
-- Only include people whose browser is known
MATCH (p:Person)
FILTER p.browserUsed IS NOT NULL
RETURN p.firstName, p.browserUsed
Используется coalesce() для замены значения по умолчанию, если свойство может иметь значение NULL:
MATCH (p:Person)
RETURN p.firstName, coalesce(p.browserUsed, 'Unknown browser') AS browser
Предостережение
NULL = NULL вычисляет значение UNKNOWN, а не TRUE. Всегда используется IS NULL для проверки значений NULL, а не равенства.
Агрегировать результаты с помощью RETURN
Используйте агрегатные функции в RETURN для суммирования ваших результатов. Graph поддерживает следующие агрегатные функции: MAX, COLLECT_ONE, COLLECT_LIST, COLLECT_ELEMENTS, MIN, AVG, SUM и COUNT.
Например, чтобы подсчитать всех людей в графе:
MATCH (p:Person)
RETURN count(*) AS totalPeople
Чтобы подсчитать уникальные значения, например, сколько отдельных компаний используют людей:
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN count(DISTINCT c) AS companyCount
Вход фильтра для одного агрегата
Добавляйте FILTER (WHERE predicate) после агрегата, чтобы фильтровать только входные данные этого агрегата. Другие агрегаты в том же RETURN по-прежнему получают все входные строки.
MATCH (p:Person)
RETURN count(*) AS allPeople,
count(*) FILTER (WHERE p.birthday < 19900101) AS peopleBornBefore1990
Добавьте LIMIT в агрегатный фильтр, чтобы использовать не более указанного числа подходящих строк. Запрос применяет предикат перед ограничением, относящимся к агрегатной функции.
MATCH (p:Person)
RETURN count(*) FILTER (WHERE p.birthday < 19900101 LIMIT 100) AS sampleCount
FILTER и LIMIT, специфичные для агрегатов, не удаляют строки из остальной части запроса. Используйте инструкцию FILTER или предикат на уровне WHERE, если нужно отфильтровать поток строк.
Собрать значения
Используйте COLLECT_LIST возврат одного элемента списка для каждого входного значения, включая null-значения. Добавляйте DISTINCT , чтобы удалить дубликаторы.
MATCH (p:Person)
RETURN collect_list(DISTINCT p.browserUsed) AS browsers
COLLECT_ONE возвращает одно ненулевое входное значение. Выбранное значение не является детерминированным, поэтому используйте его только тогда, когда любое значение из группы приемлемо.
COLLECT_ELEMENTS принимает входные данные в виде списков и объединяет их элементы в один список:
MATCH (p:Person)
RETURN collect_elements([p.firstName, p.lastName]) AS names
Без группировки столбцов агрегированный запрос без входных строк возвращает пустой список из COLLECT_LIST и COLLECT_ELEMENTS и null из COLLECT_ONE.
Группировка результатов с помощью GROUP BY
Используйте GROUP BY в RETURN для группировки строк по общим значениям и вычисления агрегатов в каждой группе. Это группирование является эквивалентом GQL SQL GROUP BY.
Например, для подсчета сотрудников на компанию:
MATCH (p:Person)-[:workAt]->(c:Company)
LET companyId = c.id, companyName = c.name
RETURN companyId, companyName, count(*) AS employeeCount
GROUP BY companyId, companyName
ORDER BY employeeCount DESC
Группировать данные по нескольким столбцам и одновременно вычислять различные агрегаты. Например, разбиение числа пользователей и диапазона дней рождения по полу и браузеру, возвращая 10 наиболее распространенных сочетаний:
MATCH (p:Person)
LET gender = p.gender
LET browser = p.browserUsed
RETURN gender,
browser,
count(*) AS personCount,
min(p.birthday) AS earliestBirthday,
max(p.birthday) AS latestBirthday
GROUP BY gender, browser
ORDER BY personCount DESC
LIMIT 10
Note
Все не агрегатные выражения в RETURN должны присутствовать в GROUP BY. Выражения, которые не находятся в GROUP BY, должны использовать агрегатную функцию.
Сортировка и ограничение агрегированных результатов
Используйте ORDER BY и LIMIT вместе с GROUP BY, чтобы найти топ-N результаты.
Например, чтобы найти первые пять городов по количеству жителей:
MATCH (p:Person)-[:isLocatedIn]->(city:City)
LET cityId = city.id, cityName = city.name
RETURN cityId, cityName, count(*) AS residentCount
GROUP BY cityId, cityName
ORDER BY residentCount DESC
LIMIT 5
Это важно
Место ORDER BY перед LIMIT.
LIMIT всегда применяется к уже отсортированному результирующему набору.
Направлять строки с помощью условных операторов
Используйте условный оператор, чтобы направлять каждую входящую строку в первую подходящую ветвь. Входные данные могут поступать с любого предыдущего этапа запроса, а не только из агрегации. Например, следующий запрос классифицирует компании после расчёта численности сотрудников:
MATCH (p:Person)-[:workAt]->(c:Company)
LET companyId = c.id, companyName = c.name
RETURN companyId, companyName, count(*) AS employeeCount
GROUP BY companyId, companyName
NEXT
WHEN employeeCount >= 100u THEN
RETURN companyId, companyName, employeeCount, 'Large' AS category
WHEN employeeCount >= 10u THEN
RETURN companyId, companyName, employeeCount, 'Medium' AS category
ELSE
RETURN companyId, companyName, employeeCount, 'Small' AS category
Ветки могут выполнять полноценные операторы запросов и вложенные процедуры, а не только возвращать выражения. Следующий пример отправляет три входных строки через разные формы ветвей. Одна ветвь запускает MATCH, одна объединяет два агрегата с UNION ALL и затем агрегирует их результаты, а резервная ветка возвращает константу:
FOR selector IN [1, 2, 3]
RETURN selector
NEXT
WHEN selector = 1 THEN
MATCH (:Person)-[:knows]->(:Person)
RETURN count(*) AS total, 'Knows edges' AS category
WHEN selector = 2 THEN {
MATCH (:Person)-[:workAt]->(:Company)
RETURN count(*) AS partialCount
UNION ALL
MATCH (:Person)-[:studyAt]->(:University)
RETURN count(*) AS partialCount
NEXT
RETURN sum(partialCount) AS total, 'Affiliation edges' AS category
}
ELSE
RETURN 0u AS total, 'No selected metric' AS category
Движок запросов оценивает предикаты в порядке для каждой строки. Он работает только на первой подходящей ветке. Если предикат вычисляется как UNKNOWN, вычисление продолжается со следующей ветвью. Без ELSE, строки, не совпадающие с WHEN ветвью, опускаются.
Условные утверждения отличаются от CASE выражений. Graph поддерживает простые CASE <expression> WHEN <value> выражения для выбора значений на основе равенства. Поисковые CASE WHEN <predicate> выражения не поддерживаются. Для получения дополнительной информации см. раздел Условные операторы.