GRAPH.QUERY
GRAPH.QUERY
GRAPH.QUERY graph query [TIMEOUT timeout]
- Доступно в:
- Redis Stack / Граф 1.0.0
- Сложность по времени:
Выполняет заданный запрос на указанном графе.
Аргументы: Graph name, Query, Timeout [optional]
Возвращает: Набор результатов
Запросы и параметризованные запросы
Планы выполнения запросов, как обычных, так и параметризованных, кешируются (до CACHE_SIZE уникальных запросов находятся в кэше). Поэтому рекомендуется использовать параметризованные запросы при выполнении многих запросов с одинаковым шаблоном, но разными константами.
Таймауты на уровне запроса могут быть настроены, как описано в разделе конфигурации.
Структура запроса:
GRAPH.QUERY graph_name "query"
пример:
GRAPH.QUERY us_government "MATCH (p:president)-[:born]->(:state {name:'Hawaii'}) RETURN p"
Структура параметризованного запроса:
GRAPH.QUERY graph_name "CYPHER param=val [param=val ...] query"
пример:
GRAPH.QUERY us_government "CYPHER state_name='Hawaii' MATCH (p:president)-[:born]->(:state {name:$state_name}) RETURN p"
Язык запросов
Синтаксис основан на Cypher. Большинство функций языка поддерживается. Ниже также описаны специфичные для RedisGraph расширения языка.
Структура запроса
- MATCH
- OPTIONAL MATCH
- WHERE
- RETURN
- ORDER BY
- SKIP
- LIMIT
- CREATE
- MERGE
- DELETE
- SET
- WITH
- UNION
- UNWIND
- FOREACH
MATCH
MATCH описывает отношения между запрашиваемыми сущностями, используя ASCII-графику для представления шаблонов для сопоставления.
Узлы представлены в скобках (), а отношения — в квадратных скобках [].
Каждый узел/отношение графа может содержать псевдоним и метку/тип отношения, но оба могут быть опушены, если это необходимо.
Структура сущности: alias:label {filters}.
Псевдоним, метка/тип отношения и фильтры являются необязательными.
Пример:
(a:Actor)-[:ACT]->(m:Movie {title:"straight outta compton"})
a — псевдоним для узла источника, к которому мы сможем обращаться в различных местах запроса.
Actor — метка, под которой этот узел помечен.
ACT — тип отношения.
m — псевдоним для узла назначения.
Movie — узел назначения типа «фильм».
{title:"straight outta compton"} — требует, чтобы атрибут «title» узла был равен «straight outta compton».
В этом примере нас интересуют сущности «актер», которые имеют отношение «act» с сущностью, представляющей фильм «straight outta compton».
Можно описать более широкие отношения, составив многоходовой запрос, например:
(me {name:'swilly'})-[:FRIENDS_WITH]->()-[:FRIENDS_WITH]->(foaf)
Здесь нас интересует, кто друзья друзей.
Узлы могут иметь более одного отношения, входящего или исходящего из них, например:
(me {name:'swilly'})-[:VISITED]->(c:Country)<-[:VISITED]-(friend)<-[:FRIENDS_WITH]-(me)
Здесь нас интересует, какие из моих друзей посетили хотя бы одну страну, в которой побывал я.
Отношения переменной длины
Узлы, находящиеся на переменном количестве отношений→узловых хопов, могут быть найдены с помощью следующего синтаксиса:
-[:TYPE*minHops..maxHops]->
TYPE, minHops и maxHops — все необязательные и по умолчанию относятся к типу, 1 и бесконечности соответственно.
Когда границы не заданы, точки можно опустить. Точки также можно опустить, когда задана только одна граница, что подразумевает шаблон фиксированной длины.
Пример:
GRAPH.QUERY DEMO_GRAPH
"MATCH (charlie:Actor { name: 'Charlie Sheen' })-[:PLAYED_WITH*1..3]->(colleague:Actor)
RETURN colleague"
Возвращает всех актеров, связанных с 'Charlie Sheen' от 1 до 3 хопов.
Двунаправленный поиск по пути
Если шаблон отношения не указывает направление, он будет соответствовать независимо от того, какой узел является источником, а какой — целью:
-[:TYPE]-
Пример:
GRAPH.QUERY DEMO_GRAPH
"MATCH (person_a:Person)-[:KNOWS]-(person_b:Person)
RETURN person_a, person_b"
Возвращает все пары людей, соединенных KNOWS отношением. Обратите внимание, что каждая пара будет возвращена дважды, один раз с каждым узлом в поле person_a и один раз в поле person_b.
Синтаксический сахар (person_a)<-[:KNOWS]->(person_b) вернёт те же результаты.
Описание ребра в квадратных скобках можно опустить, если следует рассмотреть все отношения: (person_a)--(person_b).
Именованные пути
Именованные переменные путей создаются путем присвоения пути в операторе MATCH одиночному псевдониму с синтаксисом: MATCH named_path = (path)-[to]->(capture)
Именованный путь включает все сущности в пути, независимо от того, были ли они явно обозначены псевдонимами. К именованным путям можно получить доступ, используя специально созданные встроенные функции, или возвращая их напрямую, если используется клиент языка.
Пример:
GRAPH.QUERY DEMO_GRAPH
"MATCH p=(charlie:Actor { name: 'Charlie Sheen' })-[:PLAYED_WITH*1..3]->(:Actor)
RETURN nodes(p) as actors"
Этот запрос выведет все пути, соответствующие шаблону, содержащемуся в именованном пути p. Все эти пути будут иметь общую точку начала — узел актера, представляющего Чарли Шином, но в остальном они будут различаться по длине и содержанию. Хотя итерация по пути переменной длины и конечная точка (:Actor) не обозначены явно псевдонимами, все узлы и ребра, пройденные по пути, будут включены в p. В данном случае нас интересуют только узлы каждого пути, которые мы получим с помощью встроенной функции nodes(). Возвращаемое значение будет содержать, по порядку, Чарли Шина, от 0 до 2 промежуточных узлов и неопределённую конечную точку.
Все кратчайшие пути
Функция allShortestPaths возвращает все кратчайшие пути между парой сущностей.
allShortestPaths() — это режим MATCH, в котором захватываются только самые короткие пути, удовлетворяющие всем критериям. И источник, и целевой узлы должны быть связаны в предыдущем области с WITH, чтобы вызвать allShortestPaths().
Минимальная длина (должна быть 1) и максимальная длина (должна быть как минимум 1) для поиска могут быть указаны. Может быть указано ноль или более типов отношений (например, [:R|Q*1..3]). Фильтры свойств не могут быть введены в шаблоне.
allShortestPaths() может иметь любое количество хопов для минимального и максимального значения, включая ноль. Это число определяет, сколько ребер можно пройти, выполняя шаблон, причём значение 0 означает, что узел-источник будет включён в возвращаемый путь.
Фильтры свойств поддерживаются, и может быть указано любое количество меток.
Пример:
GRAPH.QUERY DEMO_GRAPH
"MATCH (charlie:Actor {name: 'Charlie Sheen'}), (kevin:Actor {name: 'Kevin Bacon'})
WITH charlie, kevin
MATCH p=allShortestPaths((charlie)-[:PLAYED_WITH*]->(kevin))
RETURN nodes(p) as actors"
Этот запрос выведет все пути минимальной длины, соединяющие узел актера, представляющего Чарли Шина, с узлом, представляющим Кевина Бейкона. Между этими двумя актёрами существует несколько путей длиной 2, и все они будут возвращены. Вычисление путей затем завершается, так как мы не заинтересованы в каких-либо путях длиной более 2.
Пути минимального веса, ограниченной стоимости и ограниченной длины для одной пары
(С версии RedisGraph v2.10)
Процедура algo.SPpaths возвращает один, n или все пути минимального веса, [опционально] с ограниченной стоимостью, [опционально] с ограниченной длиной между парой сущностей. Каждый путь — это последовательность различных узлов, соединённых различными рёбрами.
algo.SPpaths() — это режим MATCH, в котором захватываются только пути, соответствующие всем критериям. И источник, и целевой узлы должны быть связаны в предыдущем области с WITH, чтобы вызвать algo.SPpaths().
Входные аргументы:
- Карта, содержащая:
-
sourceNode: Обязательно. Должен быть узлом -
targetNode: Обязательно. Должен быть узлом -
relTypes: Необязательно. Массив нуля или более типов отношений. Отношение должно иметь один из этих типов, чтобы быть частью пути. Если не указан или пуст: путь может содержать любое отношение. -
relDirection: Необязательно. строка. Одна из'incoming','outgoing','both'. Если не указано:'outgoing'. -
pathCount: Необязательно. Количество путей минимального веса для извлечения. Неотрицательное целое число. Если не указано: 1-
0: извлечь все пути минимального веса (все возвращаемые пути имеют одинаковый вес)Порядок: 1-й: минимальная стоимость, 2-й: минимальная длина.
-
1: извлечь один путь минимального весаЕсли существует несколько путей с одинаковым весом: (предпочтения: 1-й: минимальная стоимость, 2-й: минимальная длина)
-
n > 1: извлечь до n путей минимального веса (возвращаемые пути могут иметь разные веса)
Если существует несколько путей с одинаковым весом: (предпочтения: 1-й: минимальная стоимость, 2-й: минимальная длина)
-
-
weightProp: Необязательно. Если не указано: использовать по умолчанию вес: 1 для каждого отношения.Имя свойства, представляющего вес каждого отношения (целое число/дробное число)
Если такое свойство не существует или его значение не является положительным числом — использовать по умолчанию вес: 1
Примечание: если все веса равны: минимальный вес ≡ кратчайший путь.
-
costProp: Необязательно. Если не указано: использовать по умолчанию стоимость: 1 для каждого отношения.Имя свойства, представляющего стоимость каждого отношения (целое число/дробное число)
Если такое свойство не существует или его значение не является положительным числом — использовать по умолчанию стоимость: 1
-
maxLen: Необязательно. Максимальная длина пути (число отношений вдоль пути). Положительное целое число.Если не указано: нет ограничения по максимальной длине.
-
maxCost: Необязательно. Положительное число. Если не указано: нет ограничения по максимальной стоимости.Максимальная совокупная стоимость отношений вдоль пути.
-
Результат:
-
Пути, соответствующие входным аргументам. Для каждого отчётного пути:
-
path- путь -
pathWeight- вес пути -
pathCost- стоимость пути
Для получения дополнительной информации:
-
Длина пути может быть получена с помощью
length(path) -
Массив узлов вдоль пути может быть получен с помощью
nodes(path) -
Первый узел пути может быть получен с помощью
nodes(path)[0] -
Последний узел пути может быть получен с помощью
nodes(path)[-1] -
Массив стоимостей отношений вдоль пути может быть получен с помощью
[r in relationships(path) | r.cost], где cost - имя свойства стоимости -
Массив весов отношений вдоль пути может быть получен с помощью
[r in relationships(path) | r.weight], где weight - имя свойства веса
-
Поведение при наличии множественных рёбер:
-
Множественные рёбра — это два или более рёбра, соединяющие одну и ту же пару вершин (возможно, с различными весами и стоимостями).
-
Рассматриваются все соответствующие рёбра. Пути с одинаковыми вершинами и различными рёбрами являются разными путями. Ниже представлены 3 различных пути («n1», «n2» и «n3» — узлы; «e1», «e2», «e3» и «e4» — рёбра): (n1)-[e1]-(n2)-[e2]-(n3), (n1)-[e1]-(n2)-[e3]-(n3), (n1)-[e4]-(n2)-[e3]-(n3)
Пример:
GRAPH.QUERY DEMO_GRAPH
"MATCH (s:Actor {name: 'Charlie Sheen'}), (t:Actor {name: 'Kevin Bacon'})
CALL algo.SPpaths( {sourceNode: s, targetNode: t, relTypes: ['r1', 'r2', 'r3'], relDirection: 'outgoing', pathCount: 1, weightProp: 'weight', costProp: 'cost', maxLen: 3, maxCost: 100} )
YIELD path, pathCost, pathWeight
RETURN path ORDER BY pathCost"
Пути с минимальным весом, ограниченной стоимостью и ограниченной длиной от одного источника
(С версии RedisGraph v2.10)
Процедура algo.SSpaths возвращает один, n или все минимальные пути с [необязательно] ограниченной стоимостью и [необязательно] ограниченной длиной от заданной сущности. Каждый путь представляет собой последовательность уникальных узлов, соединённых уникальными рёбрами.
algo.SSpaths() — это режим MATCH, в котором захватываются только пути, соответствующие всем критериям. Узел источника должен быть связан в предыдущем объёме WITH для вызова algo.SSpaths().
Входные аргументы:
- Словарь, содержащий:
-
sourceNode: Обязательно. Должно быть типа узел -
relTypes: Необязательно. Массив нуля или более типов отношений. Отношение должно иметь один из этих типов, чтобы быть частью пути. Если не указано или пусто: путь может содержать любые отношения. -
relDirection: Необязательно. Строка. Одна из'incoming','outgoing','both'. Если не указано:'outgoing'. -
pathCount: Необязательно. Количество минимальных путей для извлечения. Неотрицательное целое число. Если не указано: 1Это число глобальное (не по каждой паре источник-цель); все возвращаемые пути могут иметь одну и ту же цель.
-
0: извлечь все пути с минимальным весом (все отчётные пути имеют одинаковый вес)Порядок: 1-й : минимальная стоимость, 2-й: минимальная длина.
-
1: извлечь один минимальный путьПри наличии нескольких путей с одинаковым весом: (предпочтения: 1-й : минимальная стоимость, 2-й: минимальная длина)
-
n > 1: извлечь до n минимальных путей (отчётные пути могут иметь разные веса)
При наличии нескольких путей с одинаковым весом: (предпочтения: 1-й : минимальная стоимость, 2-й: минимальная длина)
-
-
weightProp: Необязательно. Если не указано: используется значение по умолчанию — 1 для каждого отношения.Имя свойства, представляющего вес каждого отношения (целое / дробное число)
Если такое свойство не существует, или его значение не является положительным числом — используется значение по умолчанию: 1
Примечание: когда все веса равны: минимальный вес ≡ кратчайший путь.
-
costProp: Необязательно. Если не указано: используется значение по умолчанию — 1 для каждого отношения.Имя свойства, представляющего стоимость каждого отношения (целое / дробное число)
Если такое свойство не существует, или его значение не является положительным числом — используется значение по умолчанию: 1
-
maxLen: Необязательно. Максимальная длина пути (количество отношений вдоль пути). Положительное целое число.Если не указано: ограничение по максимальной длине отсутствует.
-
maxCost: Необязательно. Положительное число. Если не указано: ограничение по максимальной стоимости отсутствует.Максимальная кумулятивная стоимость для отношений вдоль пути.
-
Результат:
-
Пути, соответствующие входным аргументам. Для каждого отчётного пути:
-
path- путь -
pathWeight- вес пути -
pathCost- стоимость пути
Для получения дополнительной информации:
-
Длина пути может быть получена с помощью
length(path) -
Массив узлов вдоль пути может быть получен с помощью
nodes(path) -
Первый узел пути может быть получен с помощью
nodes(path)[0] -
Последний узел пути может быть получен с помощью
nodes(path)[-1] -
Массив стоимостей отношений вдоль пути может быть получен с помощью
[r in relationships(path) | r.cost], где cost - имя свойства стоимости -
Массив весов отношений вдоль пути может быть получен с помощью
[r in relationships(path) | r.weight], где weight - имя свойства веса
-
Поведение при наличии множественных рёбер:
-
Множественные рёбра — это два или более рёбра, соединяющие одну и ту же пару вершин (возможно, с различными весами и стоимостями).
-
Рассматриваются все соответствующие рёбра. Пути с одинаковыми вершинами и различными рёбрами являются разными путями. Ниже представлены 3 различных пути («n1», «n2» и «n3» — узлы; «e1», «e2», «e3» и «e4» — рёбра): (n1)-[e1]-(n2)-[e2]-(n3), (n1)-[e1]-(n2)-[e3]-(n3), (n1)-[e4]-(n2)-[e3]-(n3)
Пример:
GRAPH.QUERY DEMO_GRAPH
"MATCH (s:Actor {name: 'Charlie Sheen'})
CALL algo.SSpaths( {sourceNode: s, relTypes: ['r1', 'r2', 'r3'], relDirection: 'outgoing', pathCount: 1, weightProp: 'weight', costProp: 'cost', maxLen: 3, maxCost: 100} )
YIELD path, pathCost, pathWeight
RETURN path ORDER BY pathCost"
НЕОБЯЗАТЕЛЬНОЕ СОПОСТАВЛЕНИЕ
Оператор OPTIONAL MATCH — это разновидность MATCH, которая генерирует значения null для элементов, которые не соответствуют успешно, вместо логики «всё или ничего» для шаблонов в операторе MATCH.
Его можно рассматривать как выполнение той же роли, что и LEFT/RIGHT JOIN в SQL, так как сущности MATCH должны быть разрешены, но узлы и рёбра, введённые в OPTIONAL MATCH, будут возвращены как null, если они не могут быть найдены.
Оператор OPTIONAL MATCH принимает те же шаблоны, что и стандартный оператор MATCH, и может аналогичным образом модифицироваться оператором WHERE.
Несколько операторов MATCH и OPTIONAL MATCH могут быть объединены, но за обязательным MATCH не может следовать необязательный.
GRAPH.QUERY DEMO_GRAPH
"MATCH (p:Person) OPTIONAL MATCH (p)-[w:WORKS_AT]->(c:Company)
WHERE w.start_date > 2016
RETURN p, w, c"
Все Person узлы возвращаются, а также любые WORKS_AT отношения и Company узлы, которые могут быть разрешены и удовлетворяют ограничению start_date. Для каждого Person, который не разрешает необязательный шаблон, человек будет возвращён как обычно, а несоответствующие элементы будут возвращены как null.
Cypher допускает null-значения, поэтому действия, такие как обращение к свойствам и вызовы функций для null-значений, вернут null-значения, а не генерируют ошибки.
GRAPH.QUERY DEMO_GRAPH
"MATCH (p:Person) OPTIONAL MATCH (p)-[w:WORKS_AT]->(c:Company)
RETURN p, w.department, ID(c) as ID"
В этом случае w.department и ID будут возвращены, если OPTIONAL MATCH был успешным, и будут null в противном случае.
Операторы SET, CREATE, MERGE и DELETE игнорируют null-входы и выполняют ожидаемые обновления для реальных входов. Исключением является попытка создать отношение с null-концом, что вызовет ошибку:
GRAPH.QUERY DEMO_GRAPH
"MATCH (p:Person) OPTIONAL MATCH (p)-[w:WORKS_AT]->(c:Company)
CREATE (c)-[:NEW_RELATION]->(:NEW_NODE)"
Если c является null для любой записи, этот запрос выдаст ошибку. В этом случае никакие изменения в графе не производятся, даже если некоторые значения для c были разрешены.
WHERE
Этот оператор не является обязательным, но если вам нужно отфильтровать результаты, вы можете указать свои предикаты здесь.
Поддерживаемые операции:
=<><<=>>=CONTAINSENDS WITHINSTARTS WITH
Предикаты могут быть объединены с помощью AND / OR / NOT.
Обязательно заключайте предикаты в скобки для управления приоритетом.
Примеры:
WHERE (actor.name = "john doe" OR movie.rating > 8.8) AND movie.votes <= 250)
WHERE actor.age >= director.age AND actor.age > 32
Также можно указать предикаты равенства внутри узлов, используя фигурные скобки:
(:President {name:"Jed Bartlett"})-[:WON]->(:State)
Здесь мы потребовали, чтобы имя узла президента было «Jed Bartlett».
Нет никакой разницы между встроенными предикатама и предикатми, указанными в операторе WHERE.
Также возможно отфильтровывать шаблоны графов. Следующие запросы, возвращающие всех президентов и штаты, в которых они победили, дают одинаковые результаты:
MATCH (p:President), (s:State) WHERE (p)-[:WON]->(s) RETURN p, s
и
MATCH (p:President)-[:WON]->(s:State) RETURN p, s
Шаблонные предикаты также могут быть отрицаны и объединены с логическими операторами AND, OR и NOT. Следующий запрос возвращает всех президентов, которые не победили в тех штатах, где они были губернаторами:
MATCH (p:President), (s:State) WHERE NOT (p)-[:WON]->(s) AND (p)->[:governor]->(s) RETURN p, s
Узлы также могут быть отфильтрованы по метке:
MATCH (n)-[:R]->() WHERE n:L1 OR n:L2 RETURN n
Когда это возможно, предпочтительно указывать метку в шаблоне узла в операторе MATCH.
RETURN
В простом виде RETURN определяет, какие свойства будут содержать возвращаемый результат.
Его структура представляет собой список alias.property, разделённых запятыми.
Для удобства можно указать псевдоним только тогда, когда вас интересуют все атрибуты сущности, и вы не хотите указывать каждый атрибут индивидуально. Например:
RETURN movie.title, actor
Используйте ключевое слово DISTINCT для удаления дубликатов в наборе результатов:
RETURN DISTINCT friend_of_friend.name
В приведённом выше примере предположим, что у нас есть два друга, Джо и Миша, и оба знают Доминика.
DISTINCT обеспечит, что Доминик появится только один раз в конечном наборе результатов.
RETURN также может использоваться для агрегирования данных, подобно оператору group by в SQL.
После добавления агрегационной функции в список return все другие значения, не относящиеся к агрегации, рассматриваются как ключи группировки, например:
RETURN movie.title, MAX(actor.age), MIN(actor.age)
Здесь мы группируем данные по названию фильма и для каждого фильма находим возраст самого молодого и самого старшего актёра.
Агрегации
Поддерживаемые агрегационные функции включают:
avgcollectcountmaxminpercentileContpercentileDiscstDevsum
ORDER BY
ORDER BY указывает, что вывод должен быть отсортирован и как.
Вы можете сортировать по нескольким свойствам, указав каждую переменную в операторе ORDER BY.
Каждое свойство может указать порядок сортировки с помощью ASC/ASCENDING или DESC/DESCENDING. Если порядок не указан, используется восходящий порядок.
Результат будет отсортирован по первой переменной в списке.
При равных значениях будет использоваться следующее свойство в предложении ORDER BY и так далее.
ORDER BY <alias.property [ASC/DESC] list>
Ниже мы сортируем наших друзей по росту. При равном росте используется вес для устранения совпадений.
ORDER BY friend.height, friend.weight DESC
ПРОПУСК
Необязательное предложение skip позволяет пропустить указанное количество записей из набора результатов.
SKIP <number of records to skip>
Это может быть полезно при обработке результатов партиями. Например, запрос, который исследует вторую партию из 100 элементов узлов с меткой Person, будет иметь вид:
GRAPH.QUERY DEMO_GRAPH "MATCH (p:Person) RETURN p ORDER BY p.name SKIP 100 LIMIT 100"
ОГРАНИЧЕНИЕ
Хотя это не обязательно, вы можете использовать предложение limit для ограничения количества записей, возвращаемых запросом:
LIMIT <max records to return>
Если не указано, ограничений на количество возвращаемых записей нет.
СОЗДАТЬ
CREATE используется для ввода новых узлов и отношений.
Простейший пример создания одного узла:
CREATE (n)
Возможна реализация создания нескольких сущностей, разделяя их запятыми.
CREATE (n),(m)
CREATE (:Person {name: 'Kurt', age: 27})
Для добавления отношений между узлами в следующем примере сначала находится существующий исходный узел. После его нахождения создаётся новое отношение и целевой узел.
GRAPH.QUERY DEMO_GRAPH
"MATCH (a:Person)
WHERE a.name = 'Kurt'
CREATE (a)-[:MEMBER]->(:Band {name:'Nirvana'})"
Здесь исходный узел является ограниченным, а целевой узел — неограниченным.
В результате создаётся новый узел, представляющий группу Nirvana, и новое отношение связывает Курта с этой группой.
Наконец, создаётся полная схема.
Все сущности внутри схемы, которые не являются ограниченными, будут созданы.
GRAPH.QUERY DEMO_GRAPH
"CREATE (jim:Person{name:'Jim', age:29})-[:FRIENDS]->(pam:Person {name:'Pam', age:27})-[:WORKS]->(:Employer {name:'Dunder Mifflin'})"
Этот запрос создаст три узла и два отношения.
УДАЛИТЬ
DELETE используется для удаления как узлов, так и отношений.
Обратите внимание, что удаление узла также удаляет все входящие и исходящие отношения.
Для удаления узла и всех его отношений:
GRAPH.QUERY DEMO_GRAPH "MATCH (p:Person {name:'Jim'}) DELETE p"
Для удаления отношения:
GRAPH.QUERY DEMO_GRAPH "MATCH (:Person {name:'Jim'})-[r:FRIENDS]->() DELETE r"
Этот запрос удалит все friend исходящие отношения от узла с именем 'Jim'.
УСТАНОВИТЬ
SET используется для создания или обновления свойств узлов и отношений.
Для установки свойства узла используйте SET.
GRAPH.QUERY DEMO_GRAPH "MATCH (n { name: 'Jim' }) SET n.name = 'Bob'"
Если вы хотите установить несколько свойств сразу, просто разделите их запятыми, чтобы установить несколько свойств с помощью одного предложения SET.
GRAPH.QUERY DEMO_GRAPH
"MATCH (n { name: 'Jim', age:32 })
SET n.age = 33, n.name = 'Bob'"
То же самое можно сделать, установив переменную сущности графа в карту:
GRAPH.QUERY DEMO_GRAPH
"MATCH (n { name: 'Jim', age:32 })
SET n = {age: 33, name: 'Bob'}"
Использование = таким образом заменяет все предыдущие свойства сущности, в то время как += установит только явно указанные свойства.
Точно так же можно назначить или объединить полный набор свойств графовой сущности:
GRAPH.QUERY DEMO_GRAPH
"MATCH (jim {name: 'Jim'}), (pam {name: 'Pam'})
SET jim = pam"
После выполнения этого запроса узел jim будет иметь такой же набор свойств, как узел pam.
Для удаления свойства узла просто установите значение свойства в NULL.
GRAPH.QUERY DEMO_GRAPH "MATCH (n { name: 'Jim' }) SET n.name = NULL"
ОБЪЕДИНИТЬ
Предложение MERGE гарантирует существование пути в графе (либо путь уже существует, либо он должен быть создан).
MERGE либо сопоставляет существующие узлы и связывает их, либо создаёт новые данные и связывает их.
Это сочетание MATCH и CREATE, которое также позволяет указать, что произойдёт, если данные были сопоставлены или созданы.
Например, вы можете указать, что в графе должен быть узел для пользователя с определённым именем.
Если узла с правильным именем нет, будет создан новый узел, и его свойству name будет присвоено значение.
Любые псевдонимы в пути MERGE, введённые предыдущими предложениями, могут быть только сопоставлены; MERGE не будет их создавать.
Когда путь MERGE не зависит от предыдущих предложений, весь путь всегда либо будет сопоставлен, либо создан.
Если все элементы пути введены с помощью MERGE, ошибка сопоставления приведёт к созданию всех элементов, даже если часть сопоставления прошла успешно.
Путь MERGE может быть после предложения ON MATCH SET и ON CREATE SET, чтобы условно устанавливать свойства в зависимости от того, успешно ли прошло сопоставление.
Объединение узлов
Чтобы объединить один узел с меткой:
GRAPH.QUERY DEMO_GRAPH "MERGE (robert:Critic)"
Чтобы объединить один узел со свойствами:
GRAPH.QUERY DEMO_GRAPH "MERGE (charlie { name: 'Charlie Sheen', age: 10 })"
Чтобы объединить один узел, указав метку и свойство:
GRAPH.QUERY DEMO_GRAPH "MERGE (michael:Person { name: 'Michael Douglas' })"
Объединение путей
Поскольку MERGE либо сопоставляет, либо создаёт весь путь, можно случайно создать дублирующие узлы.
Например, если мы выполним следующий запрос на нашей образной схеме:
GRAPH.QUERY DEMO_GRAPH
"MERGE (charlie { name: 'Charlie Sheen '})-[r:ACTED_IN]->(wallStreet:Movie { name: 'Wall Street' })"
Даже если узел с именем 'Charlie Sheen' уже существует, весь шаблон не совпадает, поэтому будет создано 1 отношение и 2 узла — включая дублирующийся узел 'Charlie Sheen'.
Мы должны использовать несколько предложений MERGE, чтобы объединить отношение и создать только несуществующие конечные точки:
GRAPH.QUERY DEMO_GRAPH
"MERGE (charlie { name: 'Charlie Sheen' })
MERGE (wallStreet:Movie { name: 'Wall Street' })
MERGE (charlie)-[r:ACTED_IN]->(wallStreet)"
Если мы не хотим ничего создавать, если элементы шаблона не существуют, мы можем объединить предложения MATCH и MERGE. Следующий запрос объединяет отношение только в том случае, если обе его конечные точки уже существуют:
GRAPH.QUERY DEMO_GRAPH
"MATCH (charlie { name: 'Charlie Sheen' })
MATCH (wallStreet:Movie { name: 'Wall Street' })
MERGE (charlie)-[r:ACTED_IN]->(wallStreet)"
Предложения On Match и On Create
Используя ON MATCH и ON CREATE, MERGE может устанавливать свойства по-разному в зависимости от того, сопоставлен ли шаблон или создан.
В этом запросе мы объединим пути на основе списка свойств и условно установим свойство при создании новых сущностей:
GRAPH.QUERY DEMO_GRAPH
"UNWIND ['Charlie Sheen', 'Michael Douglas', 'Tamara Tunie'] AS actor_name
MATCH (movie:Movie { name: 'Wall Street' })
MERGE (person {name: actor_name})-[:ACTED_IN]->(movie)
ON CREATE SET person.first_role = movie.name"
С
Предложение WITH позволяет независимо выполнять части запросов и по-разному обрабатывать их результаты.
Это позволяет более гибко составлять запросы, а также выполнять манипуляции с данными, которые в противном случае были бы невозможны в одном запросе.
Например, если бы мы хотели найти всех детей в нашей схеме, которые старше среднего возраста всех людей:
GRAPH.QUERY DEMO_GRAPH
"MATCH (p:Person) WITH AVG(p.age) AS average_age MATCH (:Person)-[:PARENT_OF]->(child:Person) WHERE child.age > average_age return child
Это также позволяет использовать модификаторы, такие как DISTINCT, SKIP, LIMIT, и ORDER, которые в противном случае требуют RETURN предложений.
GRAPH.QUERY DEMO_GRAPH
"MATCH (u:User) WITH u AS nonrecent ORDER BY u.lastVisit LIMIT 3 SET nonrecent.should_contact = true"
РАЗМОТАТЬ
Предложение UNWIND разбивает заданный список на последовательность записей; каждая содержит один элемент из списка.
Порядок записей сохраняет исходный порядок списка.
GRAPH.QUERY DEMO_GRAPH
"CREATE (p {array:[1,2,3]})"
GRAPH.QUERY DEMO_GRAPH
"MATCH (p) UNWIND p.array AS y RETURN y"
FOREACH
(С версии RedisGraph v2.12)
Предложение FOREACH передает компоненты списка в подзапрос, состоящий только из предложений обновления (CREATE, MERGE, SET, REMOVE, DELETE и FOREACH), при этом передавая полученные записи без изменений.
Предложения внутри подзапроса распознают связанные переменные, определённые до предложения FOREACH, но являются локальными в том смысле, что последующие предложения не знают о переменных, определённых внутри них. Другими словами, FOREACH использует текущий контекст и не влияет на него.
Предложение FOREACH можно использовать для различных целей, таких как: краткое обновление и создание сущностей графа, пометка узлов\рёбер, которые удовлетворяют некоторому условию или являются частью пути, представляющего интерес, и выполнение условных запросов.
Мы показываем примеры запросов, выполняющих эти три случая использования.
Следующий запрос создаст 5 узлов, каждый с свойством v со значениями от 0 до 4, соответствующими нужному индексу в списке.
GRAPH.QUERY DEMO_GRAPH
"FOREACH(i in [1, 2, 3, 4] | CREATE (n:N {v: i}))"
Следующий запрос помечает узлы всех путей длиной до 15 км от отеля в Торонто до стейк-хауса с не менее чем 2 звёздами Мишлен.
GRAPH.QUERY DEMO_GRAPH
"MATCH p = (hotel:HOTEL {City: 'Toronto'})-[r:ROAD*..5]->(rest:RESTAURANT {type: 'Steakhouse'}) WHERE sum(r.length) <= 15 AND hotel.stars >= 4 AND rest.Michelin_stars >= 2
FOREACH(n in nodes(p) | SET n.part_of_path = true)"
Следующий запрос ищет все отели, проверяет, закупают ли они напрямую у пекарни, и если нет — гарантирует, что они помечены как покупающие у поставщика, который поставляет хлеб, и что они не закупают напрямую у пекарни.
GRAPH.QUERY DEMO_GRAPH
"MATCH (h:HOTEL) OPTIONAL MATCH (h)-[b:BUYS_FROM]->(bakery:BAKERY)
FOREACH(do_perform IN CASE WHEN b = NULL THEN [1] ELSE [] END | MERGE (h)-[b2:BUYS_FROM]->(s:SUPPLIER {supplies_bread: true}) SET b2.direct = false)"
ОБЪЕДИНЕНИЕ
Предложение UNION используется для объединения результатов нескольких запросов.
UNION объединяет результаты двух или более запросов в один набор результатов, который включает все строки, принадлежащие всем запросам в объединении.
Количество и имена столбцов должны быть одинаковыми во всех запросах, объединённых с помощью UNION.
Чтобы сохранить все строки результатов, используйте UNION ALL.
Использование только UNION объединит результаты и удалит дубликаты из набора результатов.
GRAPH.QUERY DEMO_GRAPH
"MATCH (n:Actor) RETURN n.name AS name
UNION ALL
MATCH (n:Movie) RETURN n.title AS name"
Функции
В этом разделе содержится информация обо всех поддерживаемых функциях языка запросов Cypher.
- Функции предиката
- Скалярные функции
- Функции агрегирования
- Функции списка
- Математические операторы
- Математические функции
- Тригонометрические функции
- Функции строк
- Функции точек
- Функции преобразования типов
- Функции узлов
- Функции путей
Функции предиката
| Функция | Описание |
|---|---|
| all(var IN list WHERE predicate) | Возвращает true, когда predicate истинно для всех элементов в list |
| any(var IN list WHERE predicate) | Возвращает true, когда predicate истинно хотя бы для одного элемента в list |
| exists(pattern) | Возвращает true, когда существует хотя бы одно совпадение с pattern |
| isEmpty(list|map|string) | Возвращает true, если входной список или карта не содержат элементов, или если входная строка не содержит символов Возвращает null, когда входное значение оценивается как null |
| none(var IN list WHERE predicate) | Возвращает true, когда predicate ложно для всех элементов в list |
| single(var IN list WHERE predicate) | Возвращает true, когда predicate истинно ровно для одного элемента в list |
Скалярные функции
| Функция | Описание |
|---|---|
| coalesce(expr[, expr...]) | Возвращает значение первого аргумента, которое оценивается как ненулевое значение Возвращает null, когда все аргументы оцениваются как null |
| endNode(relationship) | Возвращает целевой узел отношения Возвращает null, когда relationship оценивается как null |
| hasLabels(node, labelsList) * | Возвращает true, если node содержит все метки в labelsList, в противном случае false Возвращает true, когда labelsList оценивается как пустой список |
| id(node|relationship) | Возвращает внутренний ID узла или отношения (который не является неизменяемым) |
| labels(node) | Возвращает список строк: все метки узла node Возвращает null, когда node оценивается как null |
| properties(expr) | Когда expr является узлом или отношением: Возвращает карту, содержащую все свойства данного узла или отношения Когда expr оценивается как карта: Возвращает expr без изменений Возвращает null, когда expr оценивается как null |
| randomUUID() | Возвращает случайный UUID (универсальный уникальный идентификатор) |
| startNode(relationship) | Возвращает исходный узел отношения Возвращает null, когда relationship оценивается как null |
| timestamp() | Возвращает текущую системную метку времени (миллисекунды с начала эпохи) |
| type(relationship) | Возвращает строку: тип отношения relationship Возвращает null, когда relationship оценивается как null |
| typeOf(expr) * | (С RedisGraph v2.12) Возвращает строку: тип литерала, результата оценки выражения, псевдонима, свойства узла или свойства отношения Возвращаемое значение - одно из Map, String, Integer, Boolean, Float, Node, Edge, List, Path, Point, или Null
|
* RedisGraph-специфичные расширения Cypher
Функции агрегирования
| Функция | Описание |
|---|---|
| avg(expr) | Возвращает среднее значение набора числовых значений. Значения null игнорируются Возвращает null, когда expr не имеет оценок |
| collect(expr) | Возвращает список, содержащий все ненулевые элементы, которые были оценены из заданного выражения |
| count(expr|*) | При аргументе expr: возвращает количество ненулевых оценок expr При аргументе *: возвращает общее количество оценок (включая null) |
| max(expr) | Возвращает максимальное значение в наборе значений (с учётом упорядочивания типов). Значения null игнорируются Возвращает null, когда expr не имеет оценок |
| min(expr) | Возвращает минимальное значение в наборе значений (с учётом упорядочивания типов). Значения null игнорируются Возвращает null, когда expr не имеет оценок |
| percentileCont(expr, percentile) | Возвращает интерполированный перцентиль (между 0.0 и 1.0) по набору числовых значений. Значения null игнорируются Возвращает null, когда expr не имеет оценок |
| percentileDisc(expr, percentile) | Возвращает перцентиль ближайшего значения (между 0.0 и 1.0) по набору числовых значений. Значения null игнорируются Возвращает null, когда expr не имеет оценок |
| stDev(expr) | Возвращает выборочное стандартное отклонение по набору числовых значений. Значения null игнорируются Возвращает null, когда expr не имеет оценок |
| stDevP(expr) | Возвращает стандартное отклонение генеральной совокупности по набору числовых значений. Значения null игнорируются Возвращает null, когда expr не имеет оценок |
| sum(expr) | Возвращает сумму набора числовых значений. Значения null игнорируются Возвращает 0, когда expr не имеет оценок |
Функции списков
| Функция | Описание |
|---|---|
| head(expr) | Возвращает первый элемент списка Возвращает null, когда expr оценивается как null или пустой список |
| keys(expr) | Возвращает список строк: все имена ключей для данного отображения или все имена свойств для данного узла или ребра Возвращает null, когда expr оценивается как null |
| last(expr) | Возвращает последний элемент списка Возвращает null, когда expr оценивается как null или пустой список |
| list.dedup(list) * | (С версии RedisGraph v2.12) Для данного списка возвращает аналогичный список после удаления дублирующих элементов Порядок сохраняется, дубликаты удаляются с конца списка Возвращает null, когда list оценивается как null Выводит ошибку, когда list не оценивается как список или как null |
| list.insert(list, idx, val[, dups = TRUE]) * | (С версии RedisGraph v2.12) Для данного списка возвращает список после вставки заданного значения в заданный индекс idx имеет нулевую базу, когда неотрицателен, или с конца списка, когда отрицателен Возвращает null, когда list оценивается как null Возвращает list, когда val оценивается как null Возвращает list, когда idx оценивается как целое число, не находящееся в диапазоне [-NumItems-1 .. NumItems] Когда dups оценивается как FALSE: возвращает list, когда val оценивается как значение, которое уже является элементом list Выводит ошибку, когда list не оценивается как список или как null Выводит ошибку, когда idx не оценивается как целое число Выводит ошибку, когда dups, если указано, не оценивается как логическое значение |
| list.insertListElements(list, list2, idx[, dups = TRUE]) * | (С версии RedisGraph v2.12) Для данного списка возвращает список после вставки элементов второго списка в заданный индекс idx имеет нулевую базу, когда неотрицателен, или с конца списка, когда отрицателен Возвращает null, когда list оценивается как null Возвращает list, когда list2 оценивается как null Возвращает list, когда idx оценивается как целое число, не находящееся в диапазоне [-NumItems-1 .. NumItems] Когда dups оценивается как FALSE: если элемент list2 оценивается как элемент list, он будет пропущен; если несколько элементов list2 оцениваются как одно и то же значение - это значение будет вставлено в list не более одного раза Выводит ошибку, когда list не оценивается как список или как null Выводит ошибку, когда list2 не оценивается как список или как null Выводит ошибку, когда idx не оценивается как целое число Выводит ошибку, когда dups, если указано, не оценивается как логическое значение |
| list.remove(list, idx[, count = 1]) * | (С версии RedisGraph v2.12) Для данного списка возвращает список после удаления заданного количества последовательных элементов (или меньше, если достигнут конец списка) с начала в заданном индексе. idx имеет нулевую базу, когда неотрицателен, или с конца списка, когда отрицателен Возвращает null, когда list оценивается как null Возвращает list, когда idx оценивается как целое число, не находящееся в диапазоне [-NumItems .. NumItems-1] Возвращает list, когда count оценивается как неположительное целое число Выводит ошибку, когда list не оценивается как список или как null Выводит ошибку, когда idx не оценивается как целое число Выводит ошибку, когда count, если указано, не оценивается как целое число |
| list.sort(list[, ascending = TRUE]) * | (С версии RedisGraph v2.12) Для данного списка возвращает список с похожими элементами, но отсортированными (обратно отсортированными, если ascending оценивается как FALSE) Возвращает null, когда list оценивается как null Выводит ошибку, когда list не оценивается как список или как null Выводит ошибку, когда ascending, если указано, не оценивается как логическое значение |
| range(first, last[, step = 1]) | Возвращает список целых чисел в диапазоне [начало, конец]. step, необязательный целочисленный аргумент, представляет собой приращение между последовательными элементами |
| size(expr) | Возвращает количество элементов в списке Возвращает null, когда expr оценивается как null |
| tail(expr) | Возвращает подсписок списка, содержащий все его элементы, кроме первого Возвращает пустой список, когда expr содержит менее 2 элементов. Возвращает null, когда expr оценивается как null |
| reduce(...) | Возвращает скаляр, полученный путём оценки выражения для каждого члена списка |
* Расширения Cypher, специфичные для RedisGraph
Математические операторы
| Функция | Описание |
|---|---|
| + | Сложить два значения |
| - | Вычесть второе значение из первого |
| * | Умножить два значения |
| / | Разделить первое значение на второе |
| ^ | Возвести первое значение в степень второго |
| % | Выполнить операцию модуль первого значения на второе |
Математические функции
| Функция | Описание |
|---|---|
| abs(expr) | Возвращает абсолютное значение числового значения Возвращает null, когда expr оценивается как null |
| ceil(expr) ** | Если expr оценивается как целое число: возвращает его значение Если expr оценивается как число с плавающей точкой: возвращает число с плавающей точкой, равное наименьшему целому числу, большему или равному expr Возвращает null, когда expr оценивается как null |
| e() | Возвращает константу e, основание натурального логарифма |
| exp(expr) | Возвращает e^expr, где e — основание натурального логарифма Возвращает null, когда expr оценивается как null |
| floor(expr) ** | Если expr оценивается как целое число: возвращает его значение Если expr оценивается как число с плавающей точкой: возвращает число с плавающей точкой, равное наибольшему целому числу, меньшему или равному expr Возвращает null, когда expr оценивается как null |
| log(expr) | Возвращает натуральный логарифм числового значения Возвращает NaN, когда expr оценивается как отрицательное числовое значение, -бесконечность, когда expr оценивается как 0, и null, когда expr оценивается как null |
| log10(expr) | Возвращает логарифм по основанию 10 числового значения Возвращает NaN, когда expr оценивается как отрицательное числовое значение, -бесконечность, когда expr оценивается как 0, и null, когда expr оценивается как null |
| pow(base, exponent) * | Возвращает base, возведённое в степень exponent (эквивалентно base^exponent) Возвращает null, если любое из значений оценивается как null |
| rand() | Возвращает случайное число с плавающей точкой в диапазоне [0,1] |
| round(expr) ** *** | Если expr оценивается как целое число: возвращает его значение Если expr оценивается как число с плавающей точкой: возвращает число с плавающей точкой, равное целому числу, ближайшему к expr Возвращает null, когда expr оценивается как null |
| sign(expr) | Возвращает знак числа: 0, если expr оценивается как 0, -1, если expr оценивается как отрицательное числовое значение, и 1, если expr оценивается как положительное числовое значение Возвращает null, когда expr оценивается как null |
| sqrt(expr) | Возвращает квадратный корень числового значения Возвращает NaN, когда expr оценивается как отрицательное значение, и null, когда expr оценивается как null |
* Расширения Cypher, специфичные для RedisGraph
** Специфическое поведение RedisGraph: для избежания возможной потери точности, когда expr оценивается как целое число — результат также будет целым числом
*** Специфическое поведение RedisGraph: метод выбора при ничьей — «половина от нуля»
Тригонометрические функции
| Функция | Описание |
|---|---|
| acos(expr) | Возвращает арккосинус числового значения в радианах Возвращает nan, когда expr оценивается как числовое значение, не находящееся в диапазоне [-1, 1], и null, когда expr оценивается как null |
| asin(expr) | Возвращает арксинус числового значения в радианах Возвращает nan, когда expr оценивается как числовое значение, не находящееся в диапазоне [-1, 1], и null, когда expr оценивается как null |
| atan(expr) | Возвращает арктангенс числового значения в радианах Возвращает null, когда expr оценивается как null |
| atan2(expr, expr) | Возвращает арктангенс от пары числовых значений (декартовы координаты) в радианах Возвращает 0, когда оба выражения оцениваются как 0 Возвращает null, когда любое из выражений оценивается как null |
| cos(expr) | Возвращает косинус числового значения, представляющего угол в радианах Возвращает null, когда expr оценивается как null |
| cot(expr) | Возвращает котангенс числового значения, представляющего угол в радианах Возвращает inf, когда expr оценивается как 0, и null, когда expr оценивается как null |
| degrees(expr) | Преобразует числовое значение из радиан в градусы Возвращает null, когда expr оценивается как null |
| haversin(expr) | Возвращает половину версины числового значения, представляющего угол в радианах Возвращает null, когда expr оценивается как null |
| pi() | Возвращает математическую константу π |
| radians(expr) | Преобразует числовое значение из градусов в радианы Возвращает null, когда expr оценивается как null |
| sin(expr) | Возвращает синус числового значения, представляющего угол в радианах Возвращает null, когда expr оценивается как null |
| tan(expr) | Возвращает тангенс числового значения, представляющего угол в радианах Возвращает null, когда expr оценивается как null |
Функции для строк
| Функция | Описание |
|---|---|
| left(str, len) | Возвращает строку, содержащую len левых символов строки str Возвращает null, когда str оценивается как null, в противном случае выводит ошибку, если len оценивается как null |
| lTrim(str) | Возвращает str со удаленными начальными пробелами Возвращает null, когда str оценивается как null |
| replace(str, search, replace) | Возвращает str со всеми вхождениями search, заменёнными на replace Возвращает null, когда любое из аргументов оценивается как null |
| reverse(str) | Возвращает строку, в которой порядок всех символов в str обращён Возвращает null, когда str оценивается как null |
| right(str, len) | Возвращает строку, содержащую len правых символов строки str Возвращает null, когда str оценивается как null, в противном случае выводит ошибку, если len оценивается как null |
| rTrim(str) | Возвращает str со удаленными конечными пробелами Возвращает null, когда str оценивается как null |
| split(str, delimiter) | Возвращает список строк, полученных путём разделения str по delimiter Возвращает null, когда любой из аргументов оценивается как null |
| string.join(strList[, delimiter = '']) * | (С версии RedisGraph v2.12) Возвращает конкатенацию списка строк, используя заданный разделитель Возвращает null, когда strList оценивается как null Возвращает null, когда delimiter, если задан, оценивается как null Выводит ошибку, когда strList не оценивается как список или null Выводит ошибку, когда элемент strList не оценивается как строка Выводит ошибку, когда delimiter, если задан, не оценивается как строка или null |
| string.matchRegEx(str, regex) * | (С версии RedisGraph v2.12) Принимая строку и регулярное выражение, возвращает список всех совпадений и сопоставленных областей Возвращает пустой список, когда str оценивается как null Возвращает пустой список, когда regex оценивается как null Выводит ошибку, когда str не оценивается как строка или null Выводит ошибку, когда regex не оценивается как корректная строка регулярного выражения или null |
| string.replaceRegEx(str, regex, replacement) * | (С версии RedisGraph v2.12) Принимая строку и регулярное выражение, возвращает строку после замены каждого совпадения регулярного выражения заданной заменой Возвращает null, когда str оценивается как null Возвращает null, когда regex оценивается как null Возвращает null, когда replacement оценивается как null Выводит ошибку, когда str не оценивается как строка или null Выводит ошибку, когда regex не оценивается как корректная строка регулярного выражения или null Выводит ошибку, когда replacement не оценивается как строка или null |
| substring(str, start[, len]) | Когда len задан: возвращает подстроку str, начинающуюся с индекса start (с нуля) и имеющую длину len Когда len не задан: возвращает подстроку str, начинающуюся с индекса start (с нуля) и продолжающуюся до конца str Возвращает null, когда str оценивается как null Выводит ошибку, когда start или len оцениваются как null |
| toLower(str) | Возвращает str в нижнем регистре Возвращает null, когда str оценивается как null |
| toJSON(expr) * | Возвращает JSON представление значения Возвращает null, когда expr оценивается как null |
| toUpper(str) | Возвращает str в верхнем регистре Возвращает null, когда str оценивается как null |
| trim(str) | Возвращает str с удаленными начальными и конечными пробелами Возвращает null, когда str оценивается как null |
| size(str) | Возвращает количество символов в str Возвращает null, когда str оценивается как null |
* Расширения RedisGraph для Cypher
Функции для точек
| Функция | Описание |
|---|---|
| point(map) | Возвращает точку, представляющую координаты широты/долготы |
| distance(point1, point2) | Возвращает расстояние в метрах между двумя заданными точками Возвращает null, когда любой из аргументов оценивается как null |
Функции преобразования типов
| Функция | Описание |
|---|---|
| toBoolean(expr) | Возвращает значение Boolean, когда expr вычисляется как Boolean Преобразует строку в Boolean ( "true" (регистронезависимо) в true, "false" (регистронезависимо) в false, любое другое значение в null) Преобразует целое число в Boolean (0 в false, любые другие значения в true) Возвращает null, когда expr вычисляется как null Возвращает ошибку для других типов |
| toBooleanList(exprList) | Преобразует список в список значений Boolean. Каждый элемент списка преобразуется с помощью toBooleanOrNull() |
| toBooleanOrNull(expr) | Возвращает значение Boolean, когда expr вычисляется как Boolean Преобразует строку в Boolean ( "true" (регистронезависимо) в true, "false" (регистронезависимо) в false, любое другое значение в null) Преобразует целое число в Boolean (0 в false, любые другие значения в true) Возвращает null, когда expr вычисляется как null Возвращает null для других типов |
| toFloat(expr) | Возвращает значение с плавающей точкой, когда expr вычисляется как значение с плавающей точкой Преобразует целое число в значение с плавающей точкой Преобразует строку в значение с плавающей точкой или null Возвращает null, когда expr вычисляется как null Возвращает ошибку для других типов |
| toFloatList(exprList) | Преобразует список в список значений с плавающей точкой. Каждый элемент списка преобразуется с помощью toFloatOrNull() |
| toFloatOrNull(expr) | Возвращает значение с плавающей точкой, когда expr вычисляется как значение с плавающей точкой Преобразует целое число в значение с плавающей точкой Преобразует строку в значение с плавающей точкой или null Возвращает null, когда expr вычисляется как null Возвращает null для других типов |
| toInteger(expr) * | Возвращает целое число, когда expr вычисляется как целое число Преобразует значение с плавающей точкой в целое число Преобразует строку в целое число или null Преобразует Boolean в целое число (false в 0, true в 1) (с версии RedisGraph v2.10.8) Возвращает null, когда expr вычисляется как null Возвращает ошибку для других типов |
| toIntegerList(exprList) * | Преобразует список в список целых значений. Каждый элемент списка преобразуется с помощью toIntegerOrNull() |
| toIntegerOrNull(expr) * | Возвращает целое число, когда expr вычисляется как целое число Преобразует значение с плавающей точкой в целое число Преобразует строку в целое число или null Преобразует Boolean в целое число (false в 0, true в 1) (с версии RedisGraph v2.10.8) Возвращает null, когда expr вычисляется как null Возвращает null для других типов |
| toString(expr) | Возвращает строку, когда expr вычисляется как строка Преобразует целое число, число с плавающей точкой, Boolean, строку или точку в строковое представление Возвращает null, когда expr вычисляется как null Возвращает ошибку для других типов |
| toStringList(exprList) | Преобразует список в список строк. Каждый элемент списка преобразуется с помощью toStringOrNull() |
| toStringOrNull(expr) | Возвращает строку, когда expr вычисляется как строка Преобразует целое число, число с плавающей точкой, Boolean, строку или точку в строковое представление Возвращает null, когда expr вычисляется как null Возвращает null для других типов |
* Специфика RedisGraph: способ округления при преобразовании значения с плавающей точкой в целое — "к ближайшему меньшему целому (floor)"
Функции узлов
| Функция | Описание |
|---|---|
| indegree(node [, reltype ...]) * indegree(node [, reltypeList]) * | При отсутствии типов отношений: Возвращает количество входящих ребер узла node При указании одного или нескольких типов отношений: Возвращает количество входящих ребер узла node с указанным типом отношения Возвращает null, если node вычисляется как null Синтаксис reltypeList поддерживается с RedisGraph v2.10.8 |
| outdegree(node [, reltype ...]) * outdegree(node [, reltypeList]) * | При отсутствии типов отношений: Возвращает количество исходящих ребер узла node При указании одного или нескольких типов отношений: Возвращает количество исходящих ребер узла node с указанным типом отношения Возвращает null, если node вычисляется как null Синтаксис reltypeList поддерживается с RedisGraph v2.10.8 |
* Расширения RedisGraph для Cypher
Функции путей
| Функция | Описание |
|---|---|
| nodes(path) | Возвращает список, содержащий все узлы в path Возвращает null, если path вычисляется как null |
| relationships(path) | Возвращает список, содержащий все отношения в path Возвращает null, если path вычисляется как null |
| length(path) | Возвращает длину (количество ребер) пути path Возвращает null, если path вычисляется как null |
| shortestPath(...) * | Возвращает кратчайший путь, соответствующий заданному шаблону |
* Расширения RedisGraph для Cypher
Список выражений
Список выражений — это синтаксическая конструкция, принимающая массив и генерирующая другой на основе предоставленных инструкций по отображению и фильтрации.
Они являются распространённой конструкцией в функциональных языках и современных языках высокого уровня. В Cypher они используют синтаксис:
[element IN array WHERE condition | output elem]
-
arrayможет быть любым выражением, которое генерирует массив: литералом, ссылкой на свойство или вызовом функции. -
WHERE condition— необязательный аргумент, позволяющий отображать только элементы, удовлетворяющие определённым критериям. Если опущен, все элементы массива будут представлены в выводе. -
| output elem— необязательный аргумент, позволяющий преобразовывать элементы в выходном массиве. Если опущен, элементы вывода будут такими же, как и соответствующие входные.
Следующий запрос собирает все пути любой длины, а затем для каждого создаёт массив, содержащий свойство name каждого узла со свойством rank больше 10:
MATCH p=()-[*]->() RETURN [node IN nodes(p) WHERE node.rank > 10 | node.name]
Функции существования списка выражений
Функции any(), all(), single() и none() используют упрощённую форму синтаксиса списка выражений и возвращают булево значение.
any(element IN array WHERE condition)
Они могут работать с любым типом входного массива, но особенно полезны для фильтрации путей. Следующий запрос собирает все пути любой длины, в которых все пройденные рёбра имеют вес меньше 3:
MATCH p=()-[*]->() WHERE all(edge IN relationships(p) WHERE edge.weight < 3) RETURN p
Шаблонные выражения
Шаблонные выражения — это метод создания списка, составленного из значений, полученных путём прохождения заданного графового шаблона.
Следующий запрос возвращает имя узла Person и список возрастов всех его друзей:
MATCH (n:Person)
RETURN
n.name,
[(n)-[:FRIEND_OF]->(f:Person) | f.age]
Необязательно, в выражение шаблона можно вставить предложение WHERE, чтобы отфильтровать результаты. В этом запросе возрасты всех друзей будут собраны для дружб, начавшихся до 2010 года:
MATCH (n:Person)
RETURN
n.name,
[(n)-[e:FRIEND_OF]->(f:Person) WHERE e.since < 2010 | f.age]
CASE WHEN
Условный оператор CASE представлен в двух вариантах. Оба принимают аргумент и оценивают его по одному или нескольким выражениям. Первый WHEN аргумент, указывающий на совпадение с результатом, будет принят, и возвращено значение, указанное соответствующим ключевым словом THEN.
Необязательно, можно указать аргумент ELSE, чтобы указать, что делать, если ни один из аргументов WHEN не соответствует успешно.
В простом виде, существует только одно выражение для оценки, и оно сразу следует за ключевым словом CASE.
MATCH (n)
RETURN
CASE n.title
WHEN 'Engineer' THEN 100
WHEN 'Scientist' THEN 80
ELSE n.privileges
END
В общем виде за ключевым словом CASE не следует никакого выражения. Вместо этого каждое выражение WHEN указывает своё выражение:
MATCH (n)
RETURN
CASE
WHEN n.age < 18 THEN '0-18'
WHEN n.age < 30 THEN '18-30'
ELSE '30+'
END
Reduce
Функция reduce() принимает начальное значение и обновляет его, оценивая выражение для каждого элемента списка:
RETURN reduce(sum = 0, n IN [1,2,3] | sum + n)
sum последовательно примет значения 0, 1, 3 и 6, причём 6 будет результатом вызова функции.
Точка
Функция point() ожидает один аргумент map в формате:
RETURN point({latitude: lat_value, longitude: lon_val})
Имена ключей latitude и longitude чувствительны к регистру.
Построенная функцией точка может быть сохранена как свойство узла/отношения или использована в запросе, например, в вызове функции distance.
shortestPath
Функция shortestPath() вызывается в формате:
MATCH (a {v: 1}), (b {v: 4}) RETURN shortestPath((a)-[:L*]->(b))
Единственный аргумент shortestPath — шаблон обхода. Конечные точки этого шаблона должны быть разрешены до вызова функции, и никакие фильтры свойств не могут быть добавлены в шаблон. Шаблон отношения может указывать любое количество типов отношений (включая ноль), которые необходимо учитывать. Если указано минимальное количество ребер для обхода, оно может быть только 0 или 1, а любое число может быть использовано для максимального значения. Если указано 0 в качестве минимального значения, узел источника будет включён в возвращаемый путь. Если кратчайший путь не может быть найден, возвращается NULL.
Формат JSON
toJSON() возвращает входное значение в формате JSON. Для примитивных типов данных и массивов это преобразование стандартно. Карты и проекции карт (toJSON(node { .prop} )) преобразуются в объекты JSON, как и узлы и отношения.
Формат объекта узла в формате JSON:
{
"type": "node",
"id": id(int),
"labels": [label(string) X N],
"properties": {
property_key(string): property_value X N
}
}
Формат объекта отношения в формате JSON:
{
"type": "relationship",
"id": id(int),
"relationship": type(string),
"properties": {
property_key(string): property_value X N
}
"start": src_node(node),
"end": dest_node(node)
}
Процедуры
Процедуры вызываются с использованием синтаксиса:
GRAPH.QUERY social "CALL db.labels()"
Или вариант:
GRAPH.QUERY social "CALL db.labels() YIELD label"
Модификаторы YIELD требуются только при явном указании; по умолчанию значение в столбце «Yields» будет выводиться автоматически.
| Процедура | Аргументы | Возвращает | Описание |
|---|---|---|---|
| db.labels | ничего | label | Возвращает все метки узлов в графе. |
| db.relationshipTypes | ничего | relationshipType | Возвращает все типы отношений в графе. |
| db.propertyKeys | ничего | propertyKey | Возвращает все ключи свойств в графе. |
| db.indexes | ничего |
type, label, properties, language, stopwords, entitytype, info
| Возвращает все индексы в графе, обозначая, являются ли они точным соответствием или полным текстом, какие метки и свойства они охватывают, а также индексируют ли они атрибуты узлов или отношений. |
| db.constraints | ничего |
type, label, properties, entitytype, status
| Возвращает все ограничения в графе, обозначая тип ограничения (UNIQIE/MANDATORY), какие метки/типы отношений и свойства каждое из них применяет. |
| db.idx.fulltext.createNodeIndex |
label, property [, property ...] | ничего | Создает полнотекстовый индексируемый поиск по метке и 1 или более указанным свойствам. |
| db.idx.fulltext.drop | label | ничего | Удаляет полнотекстовый индекс, связанный с заданной меткой. |
| db.idx.fulltext.queryNodes |
label, string
|
node, score
| Получение всех узлов, содержащих указанную строку в полнотекстовых индексах по заданной метке. |
| algo.pageRank |
label, relationship-type
|
node, score
| Выполняет алгоритм PageRank над узлами заданной метки, учитывая только рёбра заданного типа отношений. |
| algo.BFS |
source-node, max-level, relationship-type
|
nodes, edges
| Выполняет поиск в ширину для поиска всех узлов, соединенных с источником. Значение max level 0 означает неограниченное, а ненулевое relationship-type определяет тип отношения, который может быть пройден. |
| dbms.procedures() | ничего |
name, mode
| Список всех процедур в DBMS, возвращает для каждой процедуры её имя и режим (чтение/запись). |
Алгоритмы
BFS
Алгоритм поиска в ширину принимает 4 аргумента:
source-node (node) - Корень поиска.
max-level (integer) - Если больше нуля, этот аргумент указывает, сколько уровней должно пройти BFS. 1 вернёт только соседей источника, 2 - все узлы в пределах 2 шагов и так далее.
relationship-type (string) - Если этот аргумент NULL, все типы отношений будут пройдены. В противном случае, он указывает единственный тип отношений для поиска в ширину.
Он может вернуть два результата:
nodes - Массив всех узлов, соединённых с источником без нарушения входных ограничений.
edges - Массив всех рёбер, пройденных во время поиска. Это не обязательно содержит все рёбра, соединяющие узлы в дереве, так как циклы или несколько рёбер, соединяющих один и тот же источник и место назначения, не влияют на проверяемую достижимость данным алгоритмом. Они могут быть использованы для построения ориентированного ациклического графа, представляющего дерево BFS. Вывод рёбер влечёт за собой небольшую потерю производительности.
Индексирование
RedisGraph поддерживает индексы для свойств узлов и типов отношений. Можно индексировать строковые, числовые и геопространственные типы данных.
Создание индекса для метки узла
Для метки узла синтаксис создания индекса:
GRAPH.QUERY DEMO_GRAPH "CREATE INDEX FOR (p:Person) ON (p.age)"
Также поддерживается старый синтаксис:
GRAPH.QUERY DEMO_GRAPH "CREATE INDEX ON :Person(age)"
После явного создания индекса он будет автоматически использоваться запросами, которые ссылаются на эту метку и любые индексированные свойства в фильтре.
GRAPH.EXPLAIN DEMO_GRAPH "MATCH (p:Person) WHERE p.age > 80 RETURN p"
1) "Results"
2) " Project"
3) " Index Scan | (p:Person)"
Это может значительно улучшить время выполнения запросов с очень специфичными фильтрами. Индекс по :employer(name), например, значительно улучшит запрос:
GRAPH.QUERY DEMO_GRAPH
"MATCH (:Employer {name: 'Dunder Mifflin'})-[:EMPLOYS]->(p:Person) RETURN p"
Пример использования геопространственного индекса для поиска Employer узлов в пределах 5 километров от Скранттона:
GRAPH.QUERY DEMO_GRAPH
"WITH point({latitude:41.4045886, longitude:-75.6969532}) AS scranton MATCH (e:Employer) WHERE distance(e.location, scranton) < 5000 RETURN e"
В настоящее время геопространственные индексы могут быть использованы только с фильтрами < и <=; поиск узлов за пределами заданного радиуса выполняется с помощью обычного поиска.
Создание индекса для типа отношения
Для типа отношения синтаксис создания индекса:
GRAPH.QUERY DEMO_GRAPH "CREATE INDEX FOR ()-[f:FOLLOW]-() ON (f.created_at)"
Затем план выполнения для использования индекса:
GRAPH.EXPLAIN DEMO_GRAPH "MATCH (p:Person {id: 0})-[f:FOLLOW]->(fp) WHERE 0 < f.created_at AND f.created_at < 1000 RETURN fp"
1) "Results"
2) " Project"
3) " Edge By Index Scan | [f:FOLLOW]"
4) " Node By Index Scan | (p:Person)"
Это может значительно улучшить время выполнения запросов, которые просматривают суперузлы или когда мы хотим начать просмотр с отношений.
Удаление индекса для метки узла
Для метки узла синтаксис удаления индекса:
GRAPH.QUERY DEMO_GRAPH "DROP INDEX ON :Person(age)"
Удаление индекса для типа отношения
Для типа отношения синтаксис удаления индекса:
GRAPH.QUERY DEMO_GRAPH "DROP INDEX ON :FOLLOW(created_at)"
Полнотекстовое индексирование
RedisGraph использует возможности индексирования RediSearch для предоставления полнотекстовых индексов через вызовы процедур.
Создание полнотекстового индекса для метки узла
Для построения полнотекстового индекса по свойству title всех узлов с меткой Movie, используйте синтаксис:
GRAPH.QUERY DEMO_GRAPH "CALL db.idx.fulltext.createNodeIndex('Movie', 'title')"
Дополнительные свойства могут быть добавлены в этот индекс, добавив их имена в вышеуказанный набор аргументов или повторно используя этот синтаксис с дополнительными именами.
GRAPH.QUERY DEMO_GRAPH "CALL db.idx.fulltext.createNodeIndex('Person', 'firstName', 'lastName')"
RediSearch предоставляет 2 варианта настройки индекса:
- Язык - Определите, какой язык использовать для стемминга текста, который добавляет основную форму слова в индекс. Это позволяет запросу «going» также возвращать результаты для «go» и «gone», например.
- Стоп-слова - Это слова, которые обычно настолько распространены, что не добавляют много информации в поиск, но занимают много места и времени процессора в индексе.
Для построения полнотекстового индекса по свойству title с использованием языка German и пользовательскими стоп-словами всех узлов с меткой Movie, используйте синтаксис:
GRAPH.QUERY DEMO_GRAPH "CALL db.idx.fulltext.createNodeIndex({ label: 'Movie', language: 'German', stopwords: ['a', 'ab'] }, 'title')"
RediSearch предоставляет 3 дополнительных варианта настройки поля:
- Вес - Важность текста в поле
- Nostem - Пропустить стемминг при индексировании текста
- Фонетический - Включить фонетический поиск по тексту
Для построения полнотекстового индекса по свойству title с фонетическим поиском всех узлов с меткой Movie, используйте синтаксис:
GRAPH.QUERY DEMO_GRAPH "CALL db.idx.fulltext.createNodeIndex('Movie', {field: 'title', phonetic: 'dm:en'})"
Использование полнотекстового индекса для метки узла
Индекс может быть вызван для сопоставления любых целых слов, содержащихся в:
GRAPH.QUERY DEMO_GRAPH
"CALL db.idx.fulltext.queryNodes('Movie', 'Book') YIELD node RETURN node.title"
1) 1) "node.title"
2) 1) 1) "The Jungle Book"
2) 1) "The Book of Life"
3) 1) "Query internal execution time: 0.927409 milliseconds"
Этот оператор CALL может быть вставлен в другие операторы Cypher для выполнения более сложных манипуляций:
GRAPH.QUERY DEMO_GRAPH
"CALL db.idx.fulltext.queryNodes('Movie', 'Book') YIELD node AS m
WHERE m.genre = 'Adventure'
RETURN m ORDER BY m.rating"
1) 1) "m"
2) 1) 1) 1) 1) "id"
2) (integer) 1168
2) 1) "labels"
2) 1) "Movie"
3) 1) "properties"
2) 1) 1) "genre"
2) "Adventure"
2) 1) "rating"
2) "7.6"
3) 1) "votes"
2) (integer) 151342
4) 1) "year"
2) (integer) 2016
5) 1) "title"
2) "The Jungle Book"
3) 1) "Query internal execution time: 0.226914 milliseconds"
Помимо возвращения совпадающих узлов, полнотекстовые индексные сканирования вернут рейтинг каждого узла. Это оценка TF-IDF узла, которая зависит от того, сколько раз поисковые термины появляются в узле и как близко они сгруппированы. Это можно наблюдать в примере:
GRAPH.QUERY DEMO_GRAPH
"CALL db.idx.fulltext.queryNodes('Node', 'hello world') YIELD node, score RETURN score, node.val"
1) 1) "score"
2) "node.val"
2) 1) 1) "2"
2) "hello world"
2) 1) "1"
2) "hello to a different world"
3) 1) "Cached execution: 1"
2) "Query internal execution time: 0.335401 milliseconds"
Удаление полнотекстового индекса для метки узла
Для удаления полнотекстового индекса синтаксис:
GRAPH.QUERY DEMO_GRAPH "CALL db.idx.fulltext.drop('Movie')"
© 2006–2022 Salvatore Sanfilippo
Licensed under the Creative Commons Attribution-ShareAlike License 4.0.
https://redis.io/commands/graph.query/