Чтобы немного повеселиться на Рождество, я подумал, что было бы здорово создать график различных всплесков на технологическом радаре ThoughtWorks и того, как рекомендации менялись с течением времени.
Я написал сценарий для извлечения каждого сообщения (например, .NET Core ) и рекомендации, сделанные на каждом радаре, в котором он появился. В итоге я получил файл CSV :
1
2
3
4
5
6
7
8
9
|
|----------------------------------------------+----------+-------------| | technology | date | suggestion | |----------------------------------------------+----------+-------------| | AppHarbor | Mar 2012 | Trial | | Accumulate-only data | Nov 2015 | Assess | | Accumulate-only data | May 2015 | Assess | | Accumulate-only data | Jan 2015 | Assess | | Buying solutions you can only afford one of | Mar 2012 | Hold | |----------------------------------------------+----------+-------------| |
Затем я написал скрипт Cypher для создания следующей графовой модели:
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
31
32
33
34
35
|
WITH [ "Hold" , "Assess" , "Trial" , "Adopt" ] AS positions UNWIND RANGE ( 0 , size(positions) - 2 ) AS index WITH positions[index] AS pos1, positions[index + 1 ] AS pos2 MERGE (position1:Position {value: pos1}) MERGE (position2:Position {value: pos2}) MERGE (position1)-[:NEXT]->(position2); load csv with headers from "file:///blips.csv" AS row MATCH (position:Position {value: row.suggestion }) MERGE (tech:Technology {name: row.technology }) MERGE (date:Date {value: row.date}) MERGE (recommendation:Recommendation { id: tech.name + "_" + date.value + "_" + position.value}) MERGE (recommendation)-[:ON_DATE]->(date) MERGE (recommendation)-[:POSITION]->(position) MERGE (recommendation)-[:TECHNOLOGY]->(tech); match (date:Date) SET date.timestamp = apoc.date.parse(date.value, "ms" , "MMM yyyy" ); MATCH (date:Date) WITH date ORDER BY date.timestamp WITH COLLECT(date) AS dates UNWIND range( 0 , size(dates)- 2 ) AS index WITH dates[index] as month1, dates[index+ 1 ] AS month2 MERGE (month1)-[:NEXT]->(month2); MATCH (tech)<-[:TECHNOLOGY]-(reco:Recommendation)-[:ON_DATE]->(date) WITH tech, reco, date ORDER BY tech.name, date.timestamp WITH tech, COLLECT(reco) AS recos UNWIND range( 0 , size(recos)- 2 ) AS index WITH recos[index] AS reco1, recos[index+ 1 ] AS reco2 MERGE (reco1)-[:NEXT]->(reco2); |
Обратите внимание, что я установил библиотеку процедур APOC, чтобы можно было преобразовать строковое представление даты в метку времени, используя функцию apoc.date.parse . Файл blips.csv должен находиться в каталоге импорта Neo4j.
Сейчас мы читаем, чтобы написать несколько запросов.
У технологического радара есть 4 позиции, которые можно занять для данной технологии: удержание, оценка, испытание и принятие:
- Hold: обрабатывать с осторожностью
- Оценить: стоит изучить с целью понять, как это повлияет на ваше предприятие.
- Судебный процесс: стоит продолжить. Важно понимать, как создать эту возможность. Предприятия должны попробовать эту технологию в проекте, который может справиться с риском.
- Принять: Мы твердо убеждены, что отрасль должна принять эти позиции. Мы используем их при необходимости в наших проектах.
Мне было любопытно, существовала ли когда-либо технология, в которой совет изначально был «Удерживать», но позже изменился на «Оценить». Я написал следующий запрос, чтобы узнать:
01
02
03
04
05
06
07
08
09
10
11
12
|
MATCH (pos1:Position {value: "Hold" })<-[:POSITION]-(reco)-[:TECHNOLOGY]->(tech), (pos2:Position {value: "Assess" })<-[:POSITION]-(otherReco)-[:TECHNOLOGY]->(tech), (reco)-[:ON_DATE]->(recoDate), (otherReco)-[:ON_DATE]->(otherRecoDate) WHERE (reco)-[:NEXT]->(otherReco) RETURN tech.name AS technology, otherRecoDate.value AS dateOfChange; ╒════════════╤══════════════╕ │ "technology" │ "dateOfChange" │ ╞════════════╪══════════════╡ │ "Azure" │ "Aug 2010" │ └────────────┴──────────────┘ |
Только лазурь ! На странице нет никакого объяснения первоначальной рекомендации «Удержание» в апреле 2010 года, которая была предположительно незадолго до того, как «облако» стало заметным. А как же наоборот? Существуют ли какие-либо технологии, в которых изначально предлагалось «оценить», а потом «провести»?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
MATCH (pos1:Position {value: "Assess" })<-[:POSITION]-(reco)-[:TECHNOLOGY]->(tech), (pos2:Position {value: "Hold" })<-[:POSITION]-(otherReco)-[:TECHNOLOGY]->(tech), (reco)-[:ON_DATE]->(recoDate), (otherReco)-[:ON_DATE]->(otherRecoDate) WHERE (reco)-[:NEXT]->(otherReco) RETURN tech.name AS technology, otherRecoDate.value AS dateOfChange; ╒═══════════════════════════════════╤══════════════╕ │ "technology" │ "dateOfChange" │ ╞═══════════════════════════════════╪══════════════╡ │ "RIA" │ "Apr 2010" │ ├───────────────────────────────────┼──────────────┤ │ "Backbone.js" │ "Oct 2012" │ ├───────────────────────────────────┼──────────────┤ │ "Pace-layered Application Strategy" │ "Nov 2015" │ ├───────────────────────────────────┼──────────────┤ │ "SPDY" │ "May 2015" │ ├───────────────────────────────────┼──────────────┤ │ "AngularJS" │ "Nov 2016" │ └───────────────────────────────────┴──────────────┘ |
Пара из них — библиотеки / фреймворки Javascript, поэтому, вероятно, сейчас советуют использовать React . Давай проверим:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
MATCH (t:Technology)<-[:TECHNOLOGY]-(reco)-[:ON_DATE]->(date), (reco)-[:POSITION]->(pos) WHERE t.name contains "React.js" RETURN pos.value, date.value ORDER BY date.timestamp ╒═══════════╤════════════╕ │ "pos.value" │ "date.value" │ ╞═══════════╪════════════╡ │ "Assess" │ "Jan 2015" │ ├───────────┼────────────┤ │ "Trial" │ "May 2015" │ ├───────────┼────────────┤ │ "Trial" │ "Nov 2015" │ ├───────────┼────────────┤ │ "Adopt" │ "Apr 2016" │ ├───────────┼────────────┤ │ "Adopt" │ "Nov 2016" │ └───────────┴────────────┘ |
Ember также популярен:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
MATCH (t:Technology)<-[:TECHNOLOGY]-(reco)-[:ON_DATE]->(date), (reco)-[:POSITION]->(pos) WHERE t.name contains "Ember" RETURN pos.value, date.value ORDER BY date.timestamp ╒═══════════╤════════════╕ │ "pos.value" │ "date.value" │ ╞═══════════╪════════════╡ │ "Assess" │ "May 2015" │ ├───────────┼────────────┤ │ "Assess" │ "Nov 2015" │ ├───────────┼────────────┤ │ "Trial" │ "Apr 2016" │ ├───────────┼────────────┤ │ "Adopt" │ "Nov 2016" │ └───────────┴────────────┘ |
Давайте пойдем по другому и посмотрим, сколько технологий было внедрено на самом последнем радаре?
1
2
3
4
5
6
7
8
9
|
MATCH (date:Date {value: "Nov 2016" })<-[:ON_DATE]-(reco) WHERE NOT (reco)<-[:NEXT]-() RETURN COUNT(*) ╒══════════╕ │ "COUNT(*)" │ ╞══════════╡ │ "45" │ └──────────┘ |
Вау, 45 новых вещей! Как они были распределены по разным позициям?
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
31
|
MATCH (date:Date {value: "Nov 2016" })<-[:ON_DATE]-(reco)-[:TECHNOLOGY]->(tech), (reco)-[:POSITION]->(position) WHERE NOT (reco)<-[:NEXT]-() WITH position, COUNT(*) AS count, COLLECT(tech.name) AS technologies ORDER BY LENGTH((position)-[:NEXT*]->()) DESC RETURN position.value, count, technologies ╒════════════════╤═══════╤══════════════════════════════════════════════╕ │ "position.value" │ "count" │ "technologies" │ ╞════════════════╪═══════╪══════════════════════════════════════════════╡ │ "Hold" │ "1" │[ "Anemic REST" ] │ ├────────────────┼───────┼──────────────────────────────────────────────┤ │ "Assess" │ "28" │[ "Nuance Mix" , "Micro frontends" , "Three.js" ,"Sc│ │ │ │ikit-learn "," WebRTC "," ReSwift "," Vue.js "," Elect│ │ │ │ron "," Container security scanning "," wit.ai "," D│ │ │ │ifferential privacy "," Rapidoid "," OpenVR "," AWS │ │ │ │Application Load Balancer "," Tarantool "," IndiaS│ │ │ │tack "," Ethereum "," axios "," Bottled Water "," Cass│ │ │ │andra carefully "," ECMAScript 2017 "," FBSnapshot│ │ │ │Testcase "," Client-directed query "," JuMP "," Cloj│ │ │ │ure.spec "," HoloLens "," Android-x86 "," Physical W│ │ │ │eb"] │ ├────────────────┼───────┼──────────────────────────────────────────────┤ │ "Trial" │ "13" │[ "tmate" ,"Lightweight Architecture Decision Re│ │ │ │cords "," APIs as a product "," JSONassert "," Unity│ │ │ │ beyond gaming "," Galen "," Enzyme "," Quick and Ni│ │ │ │mble "," Talisman "," fastlane "," Auth0 "," Pa11y "," P│ │ │ │hoenix"] │ ├────────────────┼───────┼──────────────────────────────────────────────┤ │ "Adopt" │ "3" │[ "Grafana" , "Babel" , "Pipelines as code" ] │ └────────────────┴───────┴──────────────────────────────────────────────┘ |
Много новых вещей, чтобы исследовать во время праздников! Файлы CSV, скрипт импорта и запросы, используемые в этом посте, доступны на github, если вы хотите поиграть с ними.
Ссылка: | Neo4j: создание графики технологического радара ThoughtWorks от нашего партнера по JCG Марка Нидхэма в блоге Марка Нидхэма . |