Я играл с набором данных, в котором есть расписание для национальной железной дороги в Великобритании, и они дают вам время отправления и прибытия каждого поезда в текстовом формате.
Например, узел для представления остановки может быть создан следующим образом:
1
|
CREATE (stop:Stop {arrival: "0802" , departure: "0803H" }) |
Этот формат времени не подходит для запросов, поэтому я хотел добавить еще одно свойство, которое указывало бы количество секунд с начала дня.
Поэтому мы хотим добавить в наш узел свойства прибытие-события-синг-старта и день вылета. Я написал следующий запрос, чтобы вычислить значения для этих свойств.
01
02
03
04
05
06
07
08
09
10
11
|
MATCH (stop:Stop) UNWIND [ "arrival" , "departure" ] AS key WITH key, toInteger(substring(stop[key], 0 , 2 )) AS hours, toInteger(substring(stop[key], 2 , 2 )) AS minutes, CASE WHEN substring(stop[key], 4 , 1 ) = "H" THEN 30 ELSE 0 END AS seconds WITH key, (hours * 60 * 60 ) + (minutes * 60 ) + seconds AS secondsSinceStartOfDay RETURN key + "SecondsSinceStartOfDay" AS newKey, secondsSinceStartOfDay |
1
2
3
4
5
6
7
|
╒═══════════════════════════════╤══════════════════════╕ │newKey │secondsSinceStartOfDay│ ╞═══════════════════════════════╪══════════════════════╡ │arrivalSecondsSinceStartOfDay │ 28920 │ ├───────────────────────────────┼──────────────────────┤ │departureSecondsSinceStartOfDay│ 29010 │ └───────────────────────────────┴──────────────────────┘ |
Теперь мы готовы установить эти свойства на узле «стоп».
01
02
03
04
05
06
07
08
09
10
11
12
|
MATCH (stop:Stop2) UNWIND [ "arrival" , "departure" ] AS key WITH stop, key, toInteger(substring(stop[key], 0 , 2 )) AS hours, toInteger(substring(stop[key], 2 , 2 )) AS minutes, CASE WHEN substring(stop[key], 4 , 1 ) = "H" THEN 30 ELSE 0 END AS seconds WITH stop, key, (hours * 60 * 60 ) + (minutes * 60 ) + seconds AS secondsSinceStartOfDay WITH stop, key + "SecondsSinceStartOfDay" AS newKey, secondsSinceStartOfDay SET stop[newKey] = secondsSinceStartOfDay |
1
2
3
|
Invalid input '[' : expected an identifier character, whitespace, '{' , node labels, a property map, a relationship pattern, '.' , '(' , '=' or "+=" (line 12 , column 9 (offset: 447 )) "SET stop[newKey] = secondsSinceStartOfDay" ^ |
Хм, это не сработало, как ожидалось! Похоже, мы пока не можем установить динамические свойства, используя Cypher.
К счастью, мой коллега Майкл Хангер и сообщество Neo4j курировали библиотеку процедур APOC, и у нее есть только процедура, которая нам поможет.
Вам нужно скачать jar для вашей версии Neo4j и затем поместить его в каталог плагинов . Я использую Neo4j 3.1 Beta1, так что для меня это выглядит так:
1
2
3
4
5
6
|
$ tree neo4j-enterprise-3.1.0-BETA1 /plugins/ neo4j-enterprise-3.1.0-BETA1 /plugins/ └── apoc-3.1.0.1-all.jar 0 directories, 1 file |
После этого вам нужно будет перезапустить Neo4j, чтобы он мог выбрать новые процедуры, которые мы добавили. После этого выполните следующий запрос, чтобы убедиться, что они установлены правильно:
1
2
3
4
5
|
call dbms.procedures() YIELD name WITH name WHERE name STARTS WITH "apoc" RETURN COUNT(*) |
1
2
3
4
5
|
╒════════╕ │COUNT(*)│ ╞════════╡ │ 183 │ └────────┘ |
Теперь мы готовы динамически устанавливать свойства на графике. Процедура, которую мы будем использовать, это apoc.create.setProperty, и наш запрос легко обновить, чтобы использовать его:
01
02
03
04
05
06
07
08
09
10
11
12
|
MATCH (stop:Stop) UNWIND [ "arrival" , "departure" ] AS key WITH stop, key, toInteger(substring(stop[key], 0 , 2 )) AS hours, toInteger(substring(stop[key], 2 , 2 )) AS minutes, CASE WHEN substring(stop[key], 4 , 1 ) = "H" THEN 30 ELSE 0 END AS seconds WITH stop, key, (hours * 60 * 60 ) + (minutes * 60 ) + seconds AS secondsSinceStartOfDay WITH stop, key + "SecondsSinceStartOfDay" AS newKey, secondsSinceStartOfDay CALL apoc.create.setProperty(stop, newKey, secondsSinceStartOfDay) |
1
2
3
|
Query cannot conclude with CALL (must be RETURN or an update clause) (line 12 , column 1 (offset: 439 )) "CALL apoc.create.setProperty(stop, newKey, secondsSinceStartOfDay)" ^ |
Ой, я говорил слишком рано! Нам нужно получить возвращаемый столбец процедуры и вернуть его или просто вернуть счетчик, чтобы обойти это:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
MATCH (stop:Stop) UNWIND [ "arrival" , "departure" ] AS key WITH stop, key, toInteger(substring(stop[key], 0 , 2 )) AS hours, toInteger(substring(stop[key], 2 , 2 )) AS minutes, CASE WHEN substring(stop[key], 4 , 1 ) = "H" THEN 30 ELSE 0 END AS seconds WITH stop, key, (hours * 60 * 60 ) + (minutes * 60 ) + seconds AS secondsSinceStartOfDay WITH stop, key + "SecondsSinceStartOfDay" AS newKey, secondsSinceStartOfDay CALL apoc.create.setProperty(stop, newKey, secondsSinceStartOfDay) YIELD node RETURN COUNT(*) |
1
2
3
4
5
|
╒════════╕ │COUNT(*)│ ╞════════╡ │ 2 │ └────────┘ |
И это все, теперь мы можем динамически устанавливать свойства в наших запросах.
Ссылка: | Neo4j: динамически добавлять свойство / задавать динамическое свойство от нашего партнера по JCG Марка Нидхэма в блоге Марка Нидхэма . |