Начало работы
Подключение
Тесты производительности
Развёртывание
Использование данных
Загрузка данных
Миграция данных
Запрос данных
Управление кластерами
Обновление
Глобальное обслуживание
Масштабирование
Мониторинг
Безопасность
Лучшие практики
Технические принципы
Типы данных
Хранилище
Исполняющий движок
Потоковая обработка (Domino)
MARS3 Индексы
Расширения
Расширенные функции
Расширенный запрос
Федеративные запросы
Grafana
Резервное копирование и восстановление
Аварийное восстановление
Графовая база данных
Введение
Предложения
Функции
Расширенные темы
Руководство
Настройка производительности
Устранение неполадок
Инструменты
Параметры конфигурации
SQL-команда
Часто задаваемые вопросы
Агрегатные функции — aggr(expr) — выполняются над всеми строками, соответствующими заданному ключу группировки. Ключи сравниваются на эквивалентность.
При стандартной агрегации (то есть при вызове aggr(expr)) список значений, передаваемых в агрегатную функцию, формируется из кандидатных значений после удаления всех NULL.
Примечание!
В YMatrix AGE результаты агрегации не упорядочены. Чтобы получить упорядоченный набор результатов из агрегированных данных, применяйтеORDER BYвнешне, то есть в обёртывающем SQL-запросе — за пределами функцииcypher(). УказаниеORDER BYвнутри Cypher-выражения не влияет на глобальный порядок; оно гарантирует упорядоченность только в пределах segment.
Пример:
SELECT * FROM cypher('graph_name', $$ /* aggr(expr) */ $$) AS (grouping_key agtype) ORDER BY grouping_key;
SELECT * FROM cypher('graph_name', $$
CREATE (a:Person {name: 'A', age: 13}),
(b:Person {name: 'B', age: 33, eyes: "blue"}),
(c:Person {name: 'C', age: 44, eyes: "blue"}),
(d1:Person {name: 'D', eyes: "brown"}),
(d2:Person {name: 'D'}),
(a)-[:KNOWS]->(b),
(a)-[:KNOWS]->(c),
(a)-[:KNOWS]->(d1),
(b)-[:KNOWS]->(d2),
(c)-[:KNOWS]->(d2)
$$) AS (a agtype);
Cypher предоставляет возможности агрегации, аналогичные GROUP BY в SQL. Агрегатные функции принимают набор значений и вычисляют одно сводное значение — например, avg() вычисляет среднее арифметическое числовых значений, а min() возвращает наименьшее числовое или лексикографическое значение в наборе.
Когда говорят, что агрегатная функция работает «над набором значений», имеется в виду, что внутреннее выражение (например, n.age) вычисляется для каждой записи в пределах одной группы агрегации.
Агрегации могут вычисляться по всему совпадающему набору результатов или дополнительно разбиваться с помощью ключей группировки. Ключи группировки — это неагрегатные выражения, используемые для разделения входных строк перед применением агрегатной функции.
Рассмотрим следующее выражение RETURN:
SELECT * FROM cypher('graph_name', $$
MATCH (v:Person)
RETURN v.name, count(*)
$$) AS (grouping_key agtype, count agtype);
| count | key |
|---|---|
"A" |
1 |
"B" |
1 |
"C" |
1 |
"D" |
2 |
| (1 строка) |
В нём два возвращаемых выражения: v.name и count(*). Первое не является агрегатным, поэтому оно становится неявным ключом группировки. Второе — агрегатное. Совпавшие записи группируются по значению v.name, а count(*) вычисляется один раз для каждой группы.
При агрегации с DISTINCT (то есть при вызове aggr(DISTINCT expr)) сначала из списка кандидатных значений удаляются все NULL. Затем из эквивалентных значений сохраняется только одно — дубликаты (по отношению эквивалентности) исключаются.
Оператор DISTINCT используется с агрегатами, чтобы обеспечить уникальность до того, как агрегатная функция начнёт обработку значений.
SELECT *
FROM cypher('graph_name', $$
MATCH (v:Person)
RETURN count(DISTINCT v.eyes), count(v.eyes)
$$) AS (distinct_eyes agtype, eyes agtype);
| distinct_eyes | eyes |
|---|---|
2 |
3 |
| (1 строка) |
Автоматическое поведение группировки в Cypher — когда пользователь не обязан явно объявлять ключи группировки — может приводить к неоднозначности.
SELECT * FROM cypher('graph_name', $$
CREATE (:L {a: 1, b: 2, c: 3}),
(:L {a: 2, b: 3, c: 1}),
(:L {a: 3, b: 1, c: 2})
$$) AS (a agtype);
AGE устраняет неоднозначность, требуя, чтобы любая переменная, используемая вне агрегатной функции, либо:
WITH или RETURN, либо SELECT * FROM cypher('graph_name', $$
MATCH (x:L)
RETURN x.a + count(*) + x.b + count(*) + x.c
$$) AS (a agtype);
ERROR: "x" must be either part of an explicitly listed key or used inside an aggregate function
LINE 3: RETURN x.a + count(*) + x.b + count(*) + x.c
В AGE любой неагрегатный столбец в предложении WITH или RETURN рассматривается как ключ группировки.
SELECT * FROM cypher('graph_name', $$
MATCH (x:L)
RETURN (x.a + x.b + x.c) + count(*) + count(*), x.a + x.b + x.c
$$) AS (count agtype, key agtype);
Здесь x.a + x.b + x.c служит ключом группировки. Для формирования составного ключа скобки обязательны.
| count | key |
|---|---|
12 |
6 |
| (1 строка) |
SELECT * FROM cypher('graph_name', $$
MATCH (x:L)
RETURN x.a + count(*) + x.b + count(*) + x.c, x.a, x.b, x.c
$$) AS (count agtype, a agtype, b agtype, c agtype);
Здесь x.a, x.b и x.c рассматриваются как независимые ключи группировки.
| count | a | b | c |
|---|---|---|---|
8 |
3 |
1 |
2 |
8 |
2 |
3 |
1 |
8 |
1 |
2 |
3 |
| (3 строки) |
Сама вершина или ребро может использоваться в качестве ключа группировки. При этом любые их свойства можно напрямую ссылаться в том же предложении WITH или RETURN без явного объявления.
SELECT * FROM cypher('graph_name', $$
MATCH (x:L)
RETURN count(*) + count(*) + x.a + x.b + x.c, x
$$) AS (count agtype, key agtype);
Результат группируется по x. Поскольку вершины идентифицируются по ссылке, их свойства не требуется перечислять для однозначной группировки.
Если ключ группировки необходим для агрегации, но не должен присутствовать в итоговом результате, выполните агрегацию в предложении WITH, а в RETURN передайте только нужные значения.
SELECT * FROM cypher('graph_name', $$
MATCH (x:L)
WITH count(*) + count(*) + x.a + x.b + x.c AS column, x
RETURN column
$$) AS (a agtype);
| a |
|---|
8 |
8 |
8 |
| (3 строки) |