Когда выйдет Neo4j 2.1, у нас будет предложение UNWIND , которое облегчит работу с коллекциями.
В моем блоге о создании матриц смежности мы хотели показать, сколько людей было членами первых 5 групп встреч, упорядоченных в алфавитном порядке, а затем проверить, сколько было членов каждой из других групп.
Без предложения UNWIND мы бы сделали это:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
MATCH (g:Group) WITH g ORDER BY g.name LIMIT 5 WITH COLLECT(id(g)) AS groups MATCH (g1) WHERE id(g1) IN groups MATCH (g2) WHERE id(g2) IN groups OPTIONAL MATCH path = (g1)<-[:MEMBER_OF]-()-[:MEMBER_OF]->(g2) RETURN g1.name, g2.name, CASE WHEN path is null THEN 0 ELSE COUNT(path) END AS overlap |
Здесь мы получаем первые 5 групп, помещаем их идентификаторы в коллекцию и затем создаем декартово произведение групп, выполняя спички MATCH с поиском идентификатора узла.
Если бы вместо передачи идентификаторов узлов в «группах» мы пропускали узлы, а затем использовали их в шаге MATCH, мы бы в итоге сделали полное сканирование узлов, которое становится очень медленным по мере роста хранилища.
например, эта версия будет очень медленной:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
MATCH (g:Group) WITH g ORDER BY g.name LIMIT 5 WITH COLLECT(g) AS groups MATCH (g1) WHERE g1 IN groups MATCH (g2) WHERE g2 IN groups OPTIONAL MATCH path = (g1)<-[:MEMBER_OF]-()-[:MEMBER_OF]->(g2) RETURN g1.name, g2.name, CASE WHEN path is null THEN 0 ELSE COUNT(path) END AS overlap |
Это результат исходного запроса:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
+-------------------------------------------------------------------------------------------------------------+ | g1.name | g2.name | overlap | +-------------------------------------------------------------------------------------------------------------+ | "Big Data Developers in London" | "Big Data / Data Science / Data Analytics Jobs" | 17 | | "Big Data Jobs in London" | "Big Data London" | 190 | | "Big Data London" | "Big Data Developers in London" | 244 | | "Cassandra London" | "Big Data / Data Science / Data Analytics Jobs" | 16 | | "Big Data Jobs in London" | "Big Data Developers in London" | 52 | | "Cassandra London" | "Cassandra London" | 0 | | "Big Data London" | "Big Data / Data Science / Data Analytics Jobs" | 36 | | "Big Data London" | "Cassandra London" | 422 | | "Big Data Jobs in London" | "Big Data Jobs in London" | 0 | | "Big Data / Data Science / Data Analytics Jobs" | "Big Data / Data Science / Data Analytics Jobs" | 0 | | "Big Data Jobs in London" | "Cassandra London" | 74 | | "Big Data Developers in London" | "Big Data London" | 244 | | "Cassandra London" | "Big Data Jobs in London" | 74 | | "Cassandra London" | "Big Data London" | 422 | | "Big Data / Data Science / Data Analytics Jobs" | "Big Data London" | 36 | | "Big Data Jobs in London" | "Big Data / Data Science / Data Analytics Jobs" | 20 | | "Big Data Developers in London" | "Big Data Jobs in London" | 52 | | "Cassandra London" | "Big Data Developers in London" | 69 | | "Big Data / Data Science / Data Analytics Jobs" | "Big Data Jobs in London" | 20 | | "Big Data Developers in London" | "Big Data Developers in London" | 0 | | "Big Data Developers in London" | "Cassandra London" | 69 | | "Big Data / Data Science / Data Analytics Jobs" | "Big Data Developers in London" | 17 | | "Big Data London" | "Big Data Jobs in London" | 190 | | "Big Data / Data Science / Data Analytics Jobs" | "Cassandra London" | 16 | | "Big Data London" | "Big Data London" | 0 | +-------------------------------------------------------------------------------------------------------------+ 25 rows |
Если мы используем UNWIND, нам больше не нужно передавать идентификаторы узлов, вместо этого мы можем собрать узлы в коллекцию и затем разложить их в декартово произведение:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
MATCH (g:Group) WITH g ORDER BY g.name LIMIT 5 WITH COLLECT(g) AS groups UNWIND groups AS g1 UNWIND groups AS g2 OPTIONAL MATCH path = (g1)<-[:MEMBER_OF]-()-[:MEMBER_OF]->(g2) RETURN g1.name, g2.name, CASE WHEN path is null THEN 0 ELSE COUNT(path) END AS overlap |
Там не намного меньше кода, но я думаю, что цель запроса немного яснее, если использовать UNWIND.
Я с нетерпением жду возможности увидеть инновационные способы использования UNWIND, когда 2.1 — это GA.
Ссылка: | Neo4j 2.1: Передача идентификаторов узлов против UNWIND от нашего партнера по JCG Марка Нидхэма в блоге Марка Нидхэма . |