├── README.md
└── 培训
└── 图数据库及图算法
├── cypher
├── 10-中心性算法.txt
├── 11-社区检测.txt
├── 12-相似度算法.txt
├── 6-cypher基础.txt
├── 7-load交通数据.txt
├── 8-基本图分析.txt
├── 9-路径搜索.txt
├── README.md
├── 实战-stackoverflow.txt
└── 实战-保险欺诈分析.txt
├── data
├── README.md
├── airlines.csv
├── airlines.json
├── airports.csv
├── cities.csv
├── rails.csv
├── roads.csv
├── social-nodes.csv
├── social-relationships.csv
├── sw-nodes.csv
├── sw-relationships.csv
├── transport-nodes.csv
└── transport-relationships.csv
├── iptable.txt
├── kaoshi.docx
├── procedures
├── README.md
├── dependency-reduced-pom.xml
├── pom.xml
├── procedures.iml
└── src
│ └── main
│ └── java
│ └── com
│ └── mypackage
│ ├── Procedures.java
│ └── results
│ ├── LongResult.java
│ └── StringResult.java
├── spark
├── README.md
├── 交通图
├── 图算法一__寻路问题与图算法.txt.txt
├── 图算法三__社区发现算法.txt
└── 图算法二__中心性算法.txt.txt
└── 考试.txt
/README.md:
--------------------------------------------------------------------------------
1 | #neo4j-algo - Neo4j图数据库及图算法相关资源
2 |
3 | 问题和建议:joshua.yu@graphway.ai
4 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/10-中心性算法.txt:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------
2 | //
3 | // 十、Neo4j图数据分析(三):中心性算法(Centrality)
4 | //
5 | //
6 |
7 | // 1. 计算全图中所有节点的度中心性
8 | // - 包括所有关系、和两个方向
9 | // - 同一对节点之间、一个方向上的关系只统计一次
10 | // - 结果直接返回
11 | CALL algo.degree.stream('城市', NULL, {direction: 'BOTH'})
12 | YIELD nodeId, score
13 | RETURN algo.asNode(nodeId).name AS node, score AS centrality
14 | ORDER BY centrality DESC
15 | LIMIT 20;
16 |
17 |
18 | // 2. 计算全图中所有节点的度中心性
19 | // - 包括所有关系、和两个方向
20 | // - 计算权重:distance
21 | // - 同一对节点之间、一个方向上的关系只统计一次
22 | // - 结果直接返回
23 | CALL algo.degree.stream('城市', NULL, {direction: 'BOTH', weightProperty: 'distance'})
24 | YIELD nodeId, score
25 | RETURN algo.asNode(nodeId).name AS node, score AS centrality
26 | ORDER BY centrality DESC
27 | LIMIT 20;
28 |
29 | // 3. 计算全图中所有节点的紧密中心性
30 | CALL algo.closeness.stream('城市', NULL)
31 | YIELD nodeId, centrality
32 | RETURN algo.asNode(nodeId).name AS node, centrality
33 | ORDER BY centrality DESC LIMIT 20;
34 |
35 | // 4.1 计算全图中所有节点的紧密中心性,包括非连通图
36 | CALL algo.closeness.stream('城市', NULL, {improved: true})
37 | YIELD nodeId, centrality
38 | RETURN algo.asNode(nodeId).name AS node, centrality
39 | ORDER BY centrality DESC LIMIT 20;
40 |
41 | // 5. 计算包含某节点的连通子图
42 | // - 使用APOC过程
43 | // - 关系只遍历一次
44 | MATCH (n:城市{name:'北京'})
45 | CALL apoc.path.expandConfig(n, {maxLevel: -1
46 | , relationshipFilter: '公路连接|铁路连接'
47 | , labelFilter: '城市'
48 | , uniqueness: 'RELATIONSHIP_GLOBAL'
49 | }
50 | ) YIELD path
51 | RETURN path
52 |
53 | // 6. 计算包含某节点的连通子图中所有节点的紧密中心性
54 | // - 使用APOC过程搜索连通子图
55 | // - 将#5中的查询作为参数之一
56 | // - 使用Cypher投影将子图作为参数
57 | // - 紧密中心性的结果被标准化
58 | CALL algo.closeness.stream(
59 | 'MATCH (n:城市{name:"北京"}) CALL apoc.path.expandConfig(n, {maxLevel: -1,relationshipFilter: "公路连接|铁路连接",labelFilter:"城市", uniqueness:"RELATIONSHIP_GLOBAL"}) YIELD path WITH nodes(path) AS nodes UNWIND nodes AS n RETURN DISTINCT id(n) AS id',
60 | 'MATCH (n:城市{name:"北京"}) CALL apoc.path.expandConfig(n, {maxLevel: -1,relationshipFilter: "公路连接|铁路连接",labelFilter:"城市", uniqueness:"RELATIONSHIP_GLOBAL"}) YIELD path WITH relationships(path) AS rels UNWIND rels AS rel RETURN DISTINCT id(startNode(rel)) AS source, id(endNode(rel)) AS target',
61 | {graph:'cypher'}
62 | )
63 | YIELD nodeId, centrality
64 | RETURN algo.asNode(nodeId).name AS node, centrality
65 | ORDER BY centrality DESC
66 | LIMIT 20;
67 |
68 |
69 | // 7. 计算节点的协调中心性
70 |
71 | CALL algo.closeness.harmonic.stream("城市", "公路连接|铁路连接")
72 | YIELD nodeId, centrality
73 | WITH algo.getNodeById(nodeId) AS node, centrality
74 | WHERE NOT (node:公路站点 OR node:铁路站点)
75 | RETURN node.name AS city, centrality
76 | ORDER BY centrality DESC
77 |
78 | // 8. 计算全图中所有节点的间接中心性
79 | CALL algo.betweenness.stream('城市', '铁路连接|公路连接',{direction: 'BOTH'} )
80 | YIELD nodeId, centrality
81 | RETURN algo.asNode(nodeId).name AS node, centrality
82 | ORDER BY centrality DESC
83 | LIMIT 20;
84 |
85 | // 9. 创建一个新图
86 | MERGE (home:Page {name:'Home'})
87 | MERGE (about:Page {name:'About'})
88 | MERGE (product:Page {name:'Product'})
89 | MERGE (links:Page {name:'Links'})
90 | MERGE (a:Page {name:'Site A'})
91 | MERGE (b:Page {name:'Site B'})
92 | MERGE (c:Page {name:'Site C'})
93 | MERGE (d:Page {name:'Site D'})
94 | MERGE (home)-[:LINKS]->(about)
95 | MERGE (about)-[:LINKS]->(home)
96 | MERGE (product)-[:LINKS]->(home)
97 | MERGE (home)-[:LINKS]->(product)
98 | MERGE (links)-[:LINKS]->(home)
99 | MERGE (home)-[:LINKS]->(links)
100 | MERGE (links)-[:LINKS]->(a)
101 | MERGE (a)-[:LINKS]->(home)
102 | MERGE (links)-[:LINKS]->(b)
103 | MERGE (b)-[:LINKS]->(home)
104 | MERGE (links)-[:LINKS]->(c)
105 | MERGE (c)-[:LINKS]->(home)
106 | MERGE (links)-[:LINKS]->(d)
107 | MERGE (d)-[:LINKS]->(home)
108 |
109 | // 10. 计算节点的特征向量中心性
110 | // - Page节点、LINKS关系
111 | // - 规范化结果:使用最大值作为分母转换每个节点的值到(0,1]区间
112 | CALL algo.eigenvector.stream('Page', 'LINKS', {normalization: "max"})
113 | YIELD nodeId, score
114 | WITH algo.asNode(nodeId) AS node, score
115 | RETURN node.name, score
116 | ORDER BY score DESC
117 |
118 | // 11. 计算节点的特征向量中心性
119 | // - 使用Cypher投影
120 | // - 规范化结果:使用最大值作为分母转换每个节点的值到(0,1]区间
121 | CALL algo.eigenvector.stream(
122 | 'MATCH (p:Page) RETURN id(p) as id',
123 | 'MATCH (p1:Page)-[:LINKS]->(p2:Page) RETURN id(p1) as source, id(p2) as target',
124 | {graph:'cypher', iteration:10, normalization: 'max' }
125 | ) YIELD nodeId, score
126 | WITH algo.asNode(nodeId) AS node, score
127 | RETURN node.name, score
128 | ORDER BY score DESC
129 |
130 | // 12. 计算节点的页面排行指标
131 | // - Page节点、LINKS关系
132 | CALL algo.pageRank.stream('Page', 'LINKS', {iterations:20, dampingFactor:0.85})
133 | YIELD nodeId, score
134 | WITH algo.asNode(nodeId) AS node, score
135 | RETURN node.name, score
136 | ORDER BY score DESC
137 |
138 | // 13. 计算节点的页面排行指标
139 | // - Page节点、LINKS关系
140 | // - 设置个性化节点
141 | MATCH (n:Page{name:'About'})
142 | CALL algo.pageRank.stream('Page', 'LINKS', {iterations:2, dampingFactor:0.85, sourceNodes:[n]})
143 | YIELD nodeId, score
144 | WITH algo.asNode(nodeId) AS node, score
145 | RETURN node.name, score
146 | ORDER BY score DESC
147 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/11-社区检测.txt:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------
2 | //
3 | // 十一、Neo4j图数据分析(四):社区检测算法(Community Detection)
4 | //
5 | //
6 |
7 | // 1. 计算图中三角型的数量
8 | // - 使用ALGO过程
9 | CALL algo.triangle.stream('Page','LINKS')
10 | YIELD nodeA,nodeB,nodeC
11 | RETURN algo.asNode(nodeA).name AS nodeA, algo.asNode(nodeB).name AS nodeB, algo.asNode(nodeC).name AS nodeC
12 |
13 | // 2. 计算图中每个节点参与的三角型的次数,以及聚类系数
14 | // - 使用ALGO过程
15 | CALL algo.triangleCount.stream('Page', 'LINKS', {concurrency:4})
16 | YIELD nodeId, triangles, coefficient
17 | RETURN algo.asNode(nodeId).name AS name, triangles, coefficient
18 | ORDER BY coefficient DESC
19 |
20 | // 3. 计算图中强连通分量的数量
21 | // - 使用ALGO过程
22 | CALL algo.scc.stream('Page','LINKS')
23 | YIELD nodeId, partition
24 | RETURN algo.asNode(nodeId).name, partition
25 |
26 | // 4.1 增加一个单向关系
27 | MATCH (n1:Page{name:'Links'}), (n2:Page{name:'Silo'})
28 | CREATE (n2) -[:LINKS]-> (n1)
29 |
30 | // 4.2 再次计算强连通性
31 | // - 使用ALGO过程
32 | CALL algo.scc.stream('Page','LINKS')
33 | YIELD nodeId, partition
34 | RETURN algo.asNode(nodeId).name, partition
35 |
36 | // 5. 计算图中连通分量的数量
37 | // - 使用ALGO过程
38 | // - 关系上面没有权重
39 | CALL algo.unionFind.stream('Page','LINKS')
40 | YIELD nodeId, setId
41 | RETURN algo.asNode(nodeId).name, setId
42 |
43 | // 6. 计算图中连通分量的数量
44 | // - 使用ALGO过程,结果写入节点属性
45 | // - 关系上面没有权重
46 | // - 并行操作
47 | CALL algo.unionFind.queue('Page','LINKS',{concurrency:2})
48 |
49 | // 7. 通过标签传播发现图中的社区
50 | // - 使用ALGO过程
51 | CALL algo.labelPropagation.stream("城市", "公路连接|铁路连接", { iterations: 10 })
52 | YIELD nodeId, label
53 | RETURN *
54 |
55 | // 8. 通过标签传播发现图中的社区
56 | // - 使用ALGO过程
57 | // - 为节点分配新的社区标签
58 | CALL algo.labelPropagation.stream("城市", "公路连接|铁路连接", { iterations: 10 })
59 | YIELD nodeId, label
60 | WITH nodeId, label
61 | CALL apoc.cypher.doIt('MATCH (n) WHERE id(n) = ' + nodeId + ' SET n:Group_' + label, NULL)
62 | YIELD value
63 | RETURN value
64 |
65 | // 9. 通过标签传播发现图中的社区
66 | // - 使用ALGO过程
67 | // - 使用种子标签
68 | CALL algo.labelPropagation.stream("Page", "LINKS", {
69 | iterations: 10
70 | , partitionProperty:'community'
71 | , direction:'OUTGOING' })
72 | YIELD nodeId, label
73 | RETURN nodeId, label
74 | ORDER BY label ASC, nodeId ASC
75 |
76 | // 10. 计算图的Louvain模块度,并返回最终结果
77 | // - 使用ALGO过程
78 | CALL algo.louvain.stream('城市', '公路连接|铁路连接')
79 | YIELD nodeId, community
80 | RETURN algo.asNode(nodeId).name AS node, community
81 | ORDER BY community;
82 |
83 | // 11. 计算图的Louvain模块度,将最终和中间结果写入节点属性
84 | // - 使用ALGO过程
85 | CALL algo.louvain('城市', '公路连接|铁路连接', {
86 | write:true,
87 | includeIntermediateCommunities: true,
88 | intermediateCommunitiesWriteProperty: 'communities'
89 | })
90 | YIELD nodes, communityCount, iterations, loadMillis, computeMillis, writeMillis;
91 |
92 | // 12. 查询社区划分结果,并返回结果
93 | // - 使用Cypher
94 |
95 | MATCH (n:城市)
96 | RETURN n.communities[-1] AS community, collect(n.name) AS libraries
97 | ORDER BY size(libraries) DESC
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/12-相似度算法.txt:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------
2 | //
3 | // 十二、Neo4j图数据分析(四):相似度算法(Similarity)
4 | //
5 | //
6 |
7 |
8 | // 1. 计算页面节点的Jaccard相似度,并返回最终结果
9 | // - 使用ALGO过程
10 | / - 基于直接邻居
11 | MATCH (p1:Page {name: 'Site A'}) -[:LINKS]- (p01)
12 | WITH p1, collect(id(p01)) AS p1s
13 | MATCH (p2:Page) -[:LINKS]- (p02) WHERE p1 <> p2
14 | WITH p1, p1s, p2, collect(id(p02)) AS p2s
15 | RETURN p1.name AS from,
16 | p2.name AS to,
17 | algo.similarity.jaccard(p1s, p2s) AS similarity
18 | ORDER BY similarity DESC
19 |
20 | // 2.1 计算两个向量的Jaccard相似度
21 | // - 使用ALGO过程
22 | RETURN algo.similarity.jaccard([1,2,3], [1,2,4,5]) AS similarity
23 |
24 | // 2.2 计算两个向量的重叠相似度
25 | // - 使用ALGO过程
26 | RETURN algo.similarity.overlap([1,2,3], [1,2,4,5]) AS similarity
27 |
28 | // 3. 计算所有页面节点的Jaccard相似度,并返回最终结果
29 | // - 使用ALGO过程
30 | / - 基于直接邻居
31 | MATCH (p1:Page)-[:LINKS]-(p2)
32 | WITH {item:id(p1), categories: collect(id(p2))} as userData
33 | WITH collect(userData) as data
34 | CALL algo.similarity.jaccard.stream(data)
35 | YIELD item1, item2, count1, count2, intersection, similarity
36 | RETURN algo.asNode(item1).name AS from, algo.asNode(item2).name AS to, intersection, similarity
37 | ORDER BY similarity DESC
38 |
39 | // 4.1 计算余弦相似度,并返回最终结果
40 | // - 使用ALGO过程
41 | RETURN algo.similarity.cosine([1,2,1,5], [1,2,4,5]) AS similarity
42 |
43 |
44 | // 4.2 比较Jaccard相似度对相同向量的计算结果
45 | // - 使用ALGO过程
46 | // - 如果把[1,2,1,5]变成[1,2,3,5]结果又会怎样?
47 | RETURN algo.similarity.cosine([1,2,1,5], [1,2,4,5]) AS similarity
48 |
49 |
50 | // 5. 计算余弦相似度,参照#1
51 | // - 使用ALGO过程
52 | // - 错误提示向量维度不同,解决方法参见#7
53 | MATCH (p1:Page {name: 'Site A'}) -[:LINKS]- (p01)
54 | WITH p1, collect(id(p01)) AS p1s
55 | MATCH (p2:Page) -[:LINKS]- (p02) WHERE p1 <> p2
56 | WITH p1, p1s, p2, collect(id(p02)) AS p2s
57 | RETURN p1.name AS from,
58 | p2.name AS to,
59 | algo.similarity.cosine(p1s, p2s) AS similarity
60 | ORDER BY similarity DESC
61 |
62 | // 6. 计算欧几里德相似度,并返回最终结果
63 | // - 使用ALGO过程
64 | // - 与余弦相似度相比较
65 | RETURN algo.similarity.euclideanDistance([1,2,3,5], [1,2,3,5]) AS similarity
66 |
67 | // 7.1 根据节点的直接邻居,计算其连接度向量
68 | // - 使用Cypher
69 | // i. 返回所有节点,并按照其id排序
70 | MATCH (p:Page)
71 | WITH id(p) AS pid ORDER BY id(p) ASC
72 | // ii. 将所有节点放入一个列表,然后得到所有可能的配对
73 | WITH collect(pid) AS pids
74 | UNWIND pids AS p1
75 | UNWIND pids AS p2
76 | WITH p1,p2
77 | // iii. 计算每个节点的向量 [1,0,2,...],向量的维度是节点总数, 项是关系总数
78 | MATCH (n1), (n2)
79 | WHERE id(n1) = p1 AND id(n2) = p2
80 | OPTIONAL MATCH (n1) -[l:LINKS]- (n2)
81 | WITH n1,n2, sum(CASE WHEN n1 = n2 THEN 1 WHEN l IS NULL THEN 0 ELSE 1 END) AS f
82 | // iv. 保存向量到节点的embedding属性
83 | WITH n1, collect(f) AS embedding
84 | SET n1.embedding = embedding
85 | RETURN n1.name, n1.embedding
86 |
87 | // 7.2 根据节点的连接度向量计算几何距离,并输出结果
88 | // - 使用ALGO
89 |
90 | // 返回所有节点,并按照其id排序
91 | MATCH (p:Page)
92 | WITH id(p) AS pid ORDER BY id(p) ASC
93 | // 将所有节点放入一个列表,然后得到所有可能的配对
94 | WITH collect(pid) AS pids
95 | UNWIND pids AS p1
96 | UNWIND pids AS p2
97 | WITH p1,p2 WHERE p1 < p2
98 | MATCH (n1),(n2)
99 | WHERE id(n1) = p1 AND id(n2) = p2
100 | RETURN n1.name
101 | , n2.name
102 | , algo.similarity.euclideanDistance(n1.embedding, n2.embedding) AS similarity
103 | ORDER BY similarity ASC
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/6-cypher基础.txt:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------
2 | //
3 | // 六、Cypher图数据库查询语言
4 | //
5 | //
6 |
7 | CREATE (n1:`人物` {name: '刘备'}) -[:`关系`{relationship:'兄长'}]-> (n2:`人物` {name: '关羽'}),
8 | (n2) -[:`关系`{relationship:'兄长'}]-> (n3:`人物` {name: '张飞'}),
9 | (n1) -[:`关系`{relationship:'兄长'}]-> (n3),
10 | (n1) -[:`关系`{relationship:'主公'}]-> (n4:`人物` {name: '赵云'}),
11 | (n1) -[:`关系`{relationship:'对手'}]-> (n5:`人物` {name: '曹操'});
12 |
13 |
14 |
15 | // 寻找'刘备'节点
16 | MATCH (n:人物{name:'刘备'}) RETURN n;
17 |
18 | // 寻找'刘备'节点,使用WHERE
19 | MATCH (n:人物) WHERE n.name = '刘备' RETURN n;
20 |
21 | // 寻找刘备的兄弟
22 | MATCH (n:人物{name:'刘备'}) -[:关系{relationship:'兄长'}]-> (n1) RETURN n1;
23 |
24 | // 寻找刘备的小弟(兄弟的兄弟)
25 | MATCH (n:人物{name:'刘备'}) -[:关系*2{relationship:'兄长'}]-> (n1) RETURN n1;
26 |
27 | // 寻找刘备的所有社会关系。关系可以双向。
28 | MATCH (n:人物{name:'刘备'}) -[:关系]- (n1) RETURN n1;
29 |
30 | // 如果说“兄弟的敌人是我的敌人”,试试看,能不能找到谁是张飞的敌人
31 | MATCH (n:人物{name:'张飞'}) <-[:关系*{relationship:'兄长'}]- (n1) -[:关系{relationship:'对手'}]- (n2) RETURN DISTINCT n2;
32 |
33 | // 为‘刘备’增加2个标签
34 | MATCH (n:人物{name:'刘备'}) SET n:皇帝:好人;
35 |
36 | // 显示’刘备’节点的标签和属性
37 | MATCH (n:人物{name:'刘备'}) RETURN labels(n) AS nodeLabel, keys(n) AS nodeProperties, n.name;
38 |
39 | // 删除’刘备’的’好人’标签
40 | MATCH (n:人物{name:'刘备'}) REMOVE n:好人;
41 |
42 | // 显示节点的标签和属性,以及关系的类型和属性,并以表状结构返回结果
43 | MATCH (n:人物{name:'刘备'}) -[r]- (n1)
44 | RETURN type(r) AS relationshipType, keys(r) AS relationshipProperties, labels(n1) AS nodeLabel, keys(n1) AS nodeProperties, n1.name;
45 |
46 | // 为‘刘备’增加性别属性
47 | MATCH (n:人物{name:'刘备'}) SET n.genre = '男';
48 |
49 | // 删除‘刘备’的性别属性
50 | MATCH (n:人物{name:'刘备'}) SET n.genre = NULL;
51 |
52 | // 如果节点没有关系
53 | MATCH (n:人物{name:'刘备'}) DELETE n;
54 |
55 | // 如果节点有关系,使用DETACH DELETE会先删除连接到该节点的所有关系,然后再删除节点
56 | MATCH (n:人物{name:'刘备'}) DETACH DELETE n;
57 |
58 | // 删除所有节点。如果节点有关系,也删除关系。
59 | MATCH (n) DETACH DELETE n;
60 |
61 | // 仅删除关系,保留节点
62 | MATCH (n:人物{name:'刘备'}) –[r]- () DELETE r;
63 |
64 | // 根据数据库中的节点id寻找节点
65 | MATCH (n) WHERE id(n) = 0 RETURN n;
66 |
67 | // 创建索引
68 | CREATE INDEX ON :`人物`(name);
69 |
70 | // 显示所有索引
71 | CALL db.indexes
72 |
73 | // 显示索引和限制
74 | :schema
75 |
76 | // 创建复合索引
77 | CREATE INDEX ON :`人物`(name,title);
78 |
79 | // 创建节点唯一性限制
80 | CREATE CONSTRAINT ON (person:`人物`)
81 | ASSERT person.name IS UNIQUE;
82 |
83 | // 创建节点属性存在性限制
84 | CREATE CONSTRAINT ON (person:`人物`)
85 | ASSERT exists(person.name);
86 |
87 | // 创建节点主键
88 | CREATE CONSTRAINT ON (person:`人物`)
89 | ASSERT (person.name, person.title) IS NODE KEY;
90 |
91 | // 创建关系属性的存在性限制
92 | CREATE CONSTRAINT ON ()-[r:`关系`]->()
93 | ASSERT exists(r.relationship);
94 |
95 | // 使用MERGE
96 | MERGE (n1:`人物` {name: '刘备'})
97 | MERGE (n2:`人物` {name: '刘禅'})
98 | MERGE (n1) -[:`关系`{relationship:'父亲'}]-> (n2)
99 |
100 | // 运行过程
101 | CALL dbms.procedures()
102 |
103 | // 运行函数
104 | WITH range(1,3) AS r
105 | UNWIND r AS r1
106 | RETURN sum(r1)
107 |
108 | // 显示数据库的元模型(meta graph model)
109 | CALL db.schema;
110 |
111 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/7-load交通数据.txt:
--------------------------------------------------------------------------------
1 | // =======================================================================================
2 |
3 | // 导入中国公路和铁路样例数据
4 |
5 | // 1 - 省会城市: cities.csv
6 |
7 | // 保存数据到import目录下
8 |
9 | // .1 测试读取文件
10 | LOAD CSV FROM 'file:///cities.csv' AS line
11 | WITH line LIMIT 3
12 | RETURN line
13 |
14 |
15 | // .2 读取文件头
16 |
17 | LOAD CSV WITH HEADERS FROM 'file:///cities.csv' AS line
18 | WITH line LIMIT 3
19 | RETURN line
20 |
21 |
22 | // .3 导入城市
23 |
24 | LOAD CSV WITH HEADERS FROM 'file:///cities.csv' AS line
25 | CREATE (c:城市{name: replace(line.city,"'",'')})
26 | SET c.latitude = toFloat(line.latitude)
27 | , c.longitude = toFloat(line.longitude)
28 | , c.population=toFloat(line.population)
29 | RETURN count (c)
30 |
31 |
32 | // 导入铁路数据
33 |
34 | LOAD CSV WITH HEADERS FROM 'file:///rails.csv' AS line
35 | MERGE (c1:城市{name:line.from_city})
36 | MERGE (c2:城市{name:line.to_city})
37 | MERGE (c3:城市:铁路站点{name:line.from_city+'-'+line.to_city+'-'+line.line})
38 | MERGE (c4:城市:铁路站点{name:line.to_city+'-'+line.from_city+'-'+line.line})
39 | MERGE (c3) -[r1:铁路连接{line:line.line}]-> (c4)
40 | SET r1.distance = toInteger(line.distance)
41 | ,r1.cost = toFloat(line.cost)
42 | ,r1.order = toInteger(line.order)
43 | MERGE (c1) -[r2:铁路连接{line:line.line}]-> (c3)
44 | SET r2.distance = 0
45 | ,r2.cost = 0
46 | ,r2.order = toInteger(line.order)
47 | MERGE (c4) -[r3:铁路连接{line:line.line}]-> (c2)
48 | SET r3.distance = 0
49 | ,r3.cost = 0
50 | ,r3.order = toInteger(line.order)
51 |
52 |
53 |
54 | // 导入道路数据
55 |
56 | LOAD CSV WITH HEADERS FROM 'file:///roads.csv' AS line
57 | MERGE (c1:城市{name:line.from_city})
58 | MERGE (c2:城市{name:line.to_city})
59 | MERGE (c3:城市:公路站点{name:line.from_city+'-'+line.to_city+'-'+line.road})
60 | MERGE (c4:城市:公路站点{name:line.to_city+'-'+line.from_city+'-'+line.road})
61 | MERGE (c3) -[r1:公路连接{line:line.road}]-> (c4)
62 | SET r1.distance = toInteger(line.distance)
63 | ,r1.cost = toFloat(line.cost)
64 | ,r1.order = toInteger(line.order)
65 | MERGE (c1) -[r2:公路连接{line:line.road}]-> (c3)
66 | SET r2.distance = 0
67 | ,r2.cost = 0
68 | ,r2.order = toInteger(line.order)
69 | MERGE (c4) -[r3:公路连接{line:line.road}]-> (c2)
70 | SET r3.distance = 0
71 | ,r3.cost = 0
72 | ,r3.order = toInteger(line.order)
73 |
74 |
75 |
76 | // 计算图的连通分量
77 | CALL apoc.periodic.commit("MATCH (a:城市) WHERE a.component IS NULL WITH a LIMIT 1
78 | CALL apoc.path.subgraphNodes(a, {maxLevel:-1}) YIELD node
79 | WITH node,a
80 | SET node.component = id(a)
81 | RETURN count(node)",{limit:1000})
82 |
83 |
84 | // 查询连通分量
85 |
86 | MATCH (a:城市)
87 | WITH DISTINCT a.component AS component
88 | RETURN component
89 |
90 | // ####################################
91 | // 路径寻找
92 | //
93 |
94 | // 返回从北京出发的、沿着铁路、第一站到达的城市
95 | MATCH path = (n:`城市`{name:'北京'}) <-[:位于]- () -[:铁路连接*1]-> () -[:位于]-> ()
96 | WITH path
97 | RETURN DISTINCT nodes(path)[3].name
98 |
99 | // 返回从北京出发的、沿着铁路、经过2站后可以到达的城市
100 | MATCH path = (n:`城市`{name:'北京'}) -[:铁路连接*]-> ()
101 | WITH path
102 | WHERE length(path) > 2
103 | RETURN DISTINCT nodes(path)[3].name
104 |
105 |
106 | // 返回从北京出发的、沿着铁路可以到达的所有城市及路径
107 | // 遍历顺序显示为深度优先
108 | MATCH path = (n:`城市`{name:'北京'}) <-[:位于]- () -[:铁路连接*]-> () -[:位于]-> ()
109 | WITH nodes(path) AS nodes
110 | RETURN extract(n IN nodes | n.name) AS route
111 |
112 | // 返回从北京出发的、沿着公路可以到达的所有城市及路径
113 | // 遍历顺序显示为深度优先
114 | MATCH (n:城市{name:'北京'})
115 | CALL apoc.path.expandConfig(n
116 | ,{maxLevel:-1
117 | ,bfs:true
118 | ,uniqueness:'RELATIONSHIP_GLOBAL'
119 | ,labelFilter:'+城市|公路站点|-铁路站点'
120 | ,relationshipFilter:'位于|公路连接>'}) YIELD path
121 | RETURN path
122 |
123 |
124 | // 查询所有从北京出发的、到其他城市的最短公路连接路径
125 | // 因为shortestPath只计算跳转次数,不同的公路连接在这里没有区别,所以使用DISTINCT
126 |
127 | MATCH (n1:`城市`{name:'北京'}), (n2:`城市`)
128 | WHERE id(n1) <> id(n2)
129 | WITH n1, n2
130 | MATCH path = allShortestPaths((n1) -[:公路连接*]-> (n2))
131 | WITH DISTINCT nodes(path) AS nodes
132 | RETURN extract(n IN nodes | n.name) AS route
133 |
134 | // 查询所有从北京出发的、到其他城市的最短距离路径
135 | MATCH (n1:`城市`{name:'北京'}), (n2:`城市`)
136 | WHERE id(n1) <> id(n2)
137 | WITH n1, n2
138 | CALL algo.shortestPath.stream(n1,n2,'distance') YIELD nodeId, cost
139 | RETURN algo.getNodeById(nodeId).name AS place, cost
140 |
141 | // 宽度优先遍历,使用APOC过程
142 | MATCH (n:城市{name:'北京'})
143 | CALL apoc.path.expandConfig(n,{maxLevel:-1,bfs:true,relationshipFilter:'铁路连接>'}) YIELD path
144 | RETURN extract(n IN nodes(path) | n.name) AS route
145 |
146 | // 计算两个城市之间的最短路径:
147 | // - 跳转次数最少
148 | // - 使用Cypher
149 | MATCH (start:城市{name:'无锡'}),(end:城市{name:'合肥'})
150 | ,path = allShortestPaths((start) -[:公路连接*]- (end))
151 | WITH DISTINCT nodes(path) AS nodes
152 | RETURN extract(n IN nodes | n.name) AS route
153 |
154 | // 计算两个城市之间的最短路径:
155 | // - 跳转次数最少
156 | // - 使用ALGO过程
157 | MATCH (start:城市{name:'无锡'}),(end:城市{name:'合肥'})
158 | CALL algo.shortestPath.stream(start, end, NULL, {relationshipQuery:'公路连接',direction:'BOTH'})
159 | YIELD nodeId, cost
160 | RETURN algo.getNodeById(nodeId).name AS place, cost
161 |
162 |
163 | // 计算两个城市之间的最短路径:
164 | // - 成本最低
165 | // - 设定公路的限定条件
166 | // - 使用ALGO过程
167 | MATCH (start:城市{name:'北京'}),(end:城市{name:'徐州'})
168 | CALL algo.shortestPath.stream(start, end
169 | ,'cost'
170 | ,{nodeQuery: 'MATCH (n:城市) RETURN id(n) AS id'
171 | , relationshipQuery:'MATCH (n:城市) -[r:公路连接]- (m) WHERE id(m) <> id (n) AND r.line IN ["G1","G2"] RETURN id(n) AS source, id(m) AS target, r.cost AS weight ORDER BY id(n) ASC, id(m) ASC, r.cost DESC'
172 | , direction:'BOTH'
173 | , graph:'cypher'
174 | }) YIELD nodeId, cost
175 | RETURN algo.getNodeById(nodeId).name as station,cost
176 |
177 | // 计算全图中所有节点对之间的最短距离
178 | // - 基于跳转次数
179 | // - 使用ALGO
180 | CALL algo.allShortestPaths.stream(null)
181 | YIELD sourceNodeId, targetNodeId, distance
182 | WHERE sourceNodeId < targetNodeId
183 | RETURN algo.getNodeById(sourceNodeId).name AS source
184 | ,algo.getNodeById(targetNodeId).name AS target
185 | ,distance
186 | ORDER BY distance DESC, source ASC, target ASC
187 |
188 | // 计算全图中所有节点对之间的最短距离
189 | // - 基于成本
190 | // - 使用ALGO
191 | CALL algo.allShortestPaths.stream('cost')
192 | YIELD sourceNodeId, targetNodeId, distance
193 | WHERE sourceNodeId < targetNodeId
194 | RETURN algo.getNodeById(sourceNodeId).name AS source
195 | ,algo.getNodeById(targetNodeId).name AS target
196 | ,distance AS cost
197 | ORDER BY cost DESC, source ASC, target ASC
198 |
199 | // 计算从一个城市出发,到达另一个城市的K条最短路径
200 | // - 基于距离
201 | // - 使用ALGO
202 | MATCH (start:城市 {name:'北京'}),(end:城市{name:'上海'})
203 | CALL algo.kShortestPaths.stream(start, end, 5, 'distance')
204 | YIELD index, nodeIds, costs, path
205 | RETURN index, [node in algo.getNodesById(nodeIds[1..-1]) | node.name] AS via
206 | , reduce(acc=0.0, cost in costs | acc + cost) AS totalDistance
207 |
208 | // 计算从一个城市出发的最小生成树
209 | // - 基于距离
210 | // - 使用ALGO
211 | MATCH (start:城市 {name:'北京'})
212 | CALL algo.spanningTree.minimum("城市", "铁路连接|公路连接", "distance", id(start)
213 | , {write:true, writeProperty:"MINST"})
214 | YIELD loadMillis, computeMillis, writeMillis, effectiveNodeCount
215 | RETURN loadMillis, computeMillis, writeMillis, effectiveNodeCount;
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/8-基本图分析.txt:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------
2 | //
3 | // 八、Neo4j图数据分析(一):基本图特征
4 | //
5 | //
6 |
7 | // 统计某类节点数量
8 | MATCH (n:`城市`) RETURN count(n)
9 |
10 | // 统计边的数量
11 | MATCH (n:`城市`) RETURN size((n)--())
12 |
13 | // 寻找叶子节点
14 | MATCH (n:`城市`)
15 | WHERE NOT ((n)-->()) RETURN n
16 |
17 | // 寻找根节点
18 | MATCH (n:`城市`)
19 | WHERE NOT (()-->(n)) RETURN n
20 |
21 | // 寻找度数最大的节点
22 | MATCH (a:城市)
23 | RETURN a, size((a) -- ()) AS degree
24 | ORDER BY degree DESC LIMIT 3
25 |
26 | // 计算图的直径
27 | MATCH (a:城市),(b:城市)
28 | WHERE id(b) > id(a)
29 | WITH a,b
30 | MATCH p = allShortestPaths((a) -[*..30]-> (b))
31 | RETURN length(p) AS length
32 | ORDER BY length DESC LIMIT 1
33 |
34 | // 统计节点的出度和入度
35 | MATCH (n:城市)
36 | RETURN n.name, size((n) --> ()) AS outDegree, size((n) <-- ()) AS inDegree
37 | ORDER BY outDegree, inDegree
38 |
39 | // 查询从一个城市出发能够直接到达的城市
40 | MATCH (n1:城市{name:'北京'}) -[]-> () -[r]-> () -[]-> (n2)
41 | RETURN n1.name, type(r) AS type, r.line, n2.name, r.distance
42 | ORDER BY r.distance
43 |
44 | // 查询节点的所有属性
45 | MATCH (u:城市) RETURN keys(u) LIMIT 1
46 |
47 | // 测试属性的唯一性
48 | MATCH (u:城市)
49 | RETURN count(DISTINCT u.name) AS DistinctName, count(u.name) AS TotalUser, 100*count(DISTINCT u.name)/count(u.name) AS Uniqueness;
50 |
51 | // 测试属性是否有空/NULL
52 | MATCH (u:城市) WHERE u.name IS null RETURN count(u);
53 |
54 | // 统计节点属性值的分布
55 | MATCH (n:城市)
56 | RETURN min(n.population) AS minPopulation
57 | , max(n.population) AS maxPopulation
58 | , avg(n.population) AS avgPopulation
59 | , stDev(n.population) AS stdDevPopulation;
60 |
61 | // 数据库内容采样:10%采样比率
62 | MATCH (n) WHERE rand() <= 0.1
63 | RETURN
64 | DISTINCT labels(n),
65 | count(*) AS SampleSize,
66 | avg(size(keys(n))) as Avg_PropertyCount,
67 | min(size(keys(n))) as Min_PropertyCount,
68 | max(size(keys(n))) as Max_PropertyCount,
69 | avg(size( (n)-[]-() ) ) as Avg_RelationshipCount,
70 | min(size( (n)-[]-() ) ) as Min_RelationshipCount,
71 | max(size( (n)-[]-() ) ) as Max_RelationshipCount
72 |
73 | // 寻找三角形
74 | MATCH (a)-[]-(b)-[]-(c)-[]-(a)
75 | RETURN DISTINCT a, b, c
76 |
77 | // 寻找长度为6的环
78 | MATCH path = (a:城市)-[*6]-(a)
79 | RETURN DISTINCT path
80 |
81 |
82 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/9-路径搜索.txt:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------
2 | //
3 | // 九、Neo4j图数据分析(二):路径搜索算法(Path Finding)
4 | //
5 | //
6 |
7 | // 1. 返回从北京出发的、沿着铁路、第一站到达的城市
8 | MATCH path = (n:`城市`{name:'北京'}) -[:铁路连接]-> () -[:铁路连接*1]-> () -[:铁路连接]-> ()
9 | WITH path
10 | RETURN DISTINCT nodes(path)[3].name
11 |
12 | // 2. 返回从北京出发的、沿着铁路、经过2站后可以到达的城市
13 | MATCH path = (n:`城市`{name:'北京'}) -[:铁路连接*6]-> ()
14 | WITH path
15 | RETURN DISTINCT nodes(path)[6].name
16 |
17 | // 3. 返回从北京出发的、沿着铁路可以到达的所有城市及路径
18 | // 遍历顺序显示为深度优先
19 | MATCH path = (n:`城市`{name:'北京'}) -[:铁路连接*]-> ()
20 | WITH nodes(path) AS nodes
21 | WITH filter(x IN nodes WHERE NOT x:铁路站点) AS cities
22 | RETURN DISTINCT extract(c1 IN cities | c1.name) AS route
23 |
24 | // 宽度优先遍历,使用APOC过程,返回中转和目的城市
25 | MATCH (n:城市{name:'北京'})
26 | CALL apoc.path.expandConfig(n
27 | ,{maxLevel:-1
28 | ,bfs:true
29 | ,uniqueness:'RELATIONSHIP_GLOBAL'
30 | ,labelFilter:'+城市|-公路站点'
31 | ,relationshipFilter:'铁路连接>'}
32 | ) YIELD path
33 | WITH filter(n IN nodes(path) WHERE NOT n:铁路站点) AS route
34 | RETURN DISTINCT extract(n IN route | n.name)
35 |
36 | // 4. 计算两个城市之间的最短路径:
37 | // - 跳转次数最少
38 | // - 使用Cypher
39 | MATCH (start:城市{name:'天津'}),(end:城市{name:'石家庄'})
40 | ,path = allShortestPaths((start) -[:公路连接*]- (end))
41 | WITH DISTINCT nodes(path) AS nodes
42 | RETURN extract(n IN nodes | n.name) AS route
43 |
44 | // 5. 计算两个城市之间的最短路径:
45 | // - 跳转次数最少
46 | // - 使用ALGO过程
47 | MATCH (start:城市{name:'天津'}),(end:城市{name:'石家庄'})
48 | CALL algo.shortestPath.stream(start, end, NULL,
49 | {relationshipQuery:'公路连接'
50 | ,direction:'BOTH'
51 | }
52 | )
53 | YIELD nodeId, cost
54 | WITH nodeId, cost
55 | RETURN algo.getNodeById(nodeId).name AS city
56 |
57 | // 6. 计算两个城市之间的最短路径:
58 | // - 距离最短
59 | // - 仅限公路
60 | // - 使用ALGO过程
61 | MATCH (start:城市{name:'天津'}),(end:城市{name:'石家庄'})
62 | CALL algo.shortestPath.stream(start, end, 'distance',
63 | {relationshipQuery:'公路连接'
64 | ,direction:'BOTH'
65 | }
66 | )
67 | YIELD nodeId, cost
68 | WITH nodeId, cost
69 | RETURN algo.getNodeById(nodeId).name AS city, cost
70 |
71 | // 7. 计算两个城市之间的最短路径:
72 | // - 成本最低
73 | // - 不限连接类型
74 | // - 使用ALGO过程
75 | MATCH (start:城市{name:'天津'}),(end:城市{name:'石家庄'})
76 | CALL algo.shortestPath.stream(start, end, 'cost',
77 | { direction:'BOTH'
78 | }
79 | )
80 | YIELD nodeId, cost
81 | WITH nodeId, cost
82 | RETURN algo.getNodeById(nodeId).name AS city, cost
83 |
84 | // 8. 计算两个城市之间的最短路径:
85 | // - 成本最低
86 | // - 不能使用公路G3
87 | // - 使用Cypher得到子图投影(projection)
88 | // - 使用ALGO过程
89 | MATCH (start:城市{name:'天津'}),(end:城市{name:'石家庄'})
90 | CALL algo.shortestPath.stream(start, end
91 | ,'cost'
92 | ,{nodeQuery: 'MATCH (n:城市) RETURN id(n) AS id'
93 | , relationshipQuery:'MATCH (n:城市) -[r:公路连接]- (m) WHERE id(m) <> id (n) AND r.line <> \'G3\' RETURN id(n) AS source, id(m) AS target, r.cost AS weight ORDER BY id(n) ASC, id(m) ASC'
94 | , direction:'BOTH'
95 | , graph:'cypher'
96 | }) YIELD nodeId, cost
97 | RETURN algo.getNodeById(nodeId).name as station,cost
98 |
99 | // 9. 计算从一个城市出发,到达所有其他城市的最短路径
100 | // - 基于跳转次数
101 | // - 使用Cypher
102 | MATCH (n:城市 {name:'北京'})
103 | MATCH (m:城市) WHERE id(m) <> id(n)
104 | MATCH path = shortestPath((n) -[*]- (m))
105 | WITH filter(x IN nodes(path) WHERE NOT x:铁路站点 AND NOT x:公路站点) AS cities
106 | RETURN DISTINCT extract(n IN cities | n.name) AS route
107 |
108 |
109 | // 10. 计算从一个城市出发,到达所有其他城市的最短路径
110 | // - 基于成本
111 | // - 使用ALGO
112 | MATCH (n:城市 {name:'北京'})
113 | CALL algo.shortestPath.deltaStepping.stream(n, 'cost',1.0)
114 | YIELD nodeId, distance
115 | WITH algo.getNodeById(nodeId) AS destination, distance AS cost
116 | WHERE NOT destination:公路站点 AND NOT destination:铁路站点
117 | RETURN destination.name, cost
118 | ORDER BY cost
119 |
120 | // 11. 计算全图中所有节点对之间的最短距离
121 | // - 基于跳转次数
122 | // - 使用ALGO
123 | CALL algo.allShortestPaths.stream(null)
124 | YIELD sourceNodeId, targetNodeId, distance
125 | WHERE sourceNodeId < targetNodeId
126 | WITH algo.getNodeById(sourceNodeId) AS source
127 | ,algo.getNodeById(targetNodeId) AS target
128 | ,distance
129 | WHERE NOT (source:公路站点 OR source:铁路站点) AND NOT (target:公路站点 OR target:铁路站点)
130 | RETURN source.name, target.name, distance
131 | ORDER BY distance DESC, source ASC, target ASC
132 |
133 | // 12. 计算全图中所有节点对之间的最短距离
134 | // - 基于成本
135 | // - 使用ALGO
136 | CALL algo.allShortestPaths.stream('cost')
137 | YIELD sourceNodeId, targetNodeId, distance
138 | WHERE sourceNodeId < targetNodeId
139 | WITH algo.getNodeById(sourceNodeId) AS source
140 | ,algo.getNodeById(targetNodeId) AS target
141 | ,distance AS cost
142 | WHERE NOT (source:公路站点 OR source:铁路站点) AND NOT (target:公路站点 OR target:铁路站点)
143 | RETURN source.name, target.name, cost
144 | ORDER BY cost DESC, source ASC, target ASC
145 |
146 | // 13. 计算从一个城市出发,到达另一个城市的K条最短路径
147 | // - 基于距离
148 | // - 使用ALGO
149 | MATCH (start:城市 {name:'北京'}),(end:城市{name:'上海'})
150 | CALL algo.kShortestPaths.stream(start, end, 3, 'distance')
151 | YIELD index, nodeIds, costs
152 | // 创建一个大小和nodeIds相同的整数数组作为循环变量i
153 | WITH index, nodeIds, costs, range(0,size(nodeIds)-1) AS iterators
154 | UNWIND iterators AS i
155 | // 过滤nodeIds数组中有‘铁路站点’或‘公路站点’标签的节点
156 | WITH index, nodeIds[i] AS nid, costs[i+1] AS cost,
157 | algo.getNodeById(nodeIds[i]) AS node
158 | WHERE NOT (node:公路站点 OR node:铁路站点)
159 | // 计算总成本
160 | WITH index, collect(node.name) AS route, sum(cost) AS totalCost
161 | RETURN index, route, totalCost
162 | ORDER BY index ASC
163 |
164 | // 14. 计算从一个城市出发到达最多其他城市的最小生成树
165 | // - 基于距离
166 | // - 创建新关系MSTALL,并以属性distance保存最短距离
167 | MATCH (n:城市 {name:"北京"})
168 | CALL algo.spanningTree.minimum("城市", "公路连接|铁路连接", "distance", id(n),
169 | {write:true, writeProperty:"MSTALL"}
170 | )
171 | YIELD loadMillis, computeMillis, writeMillis, effectiveNodeCount
172 | RETURN loadMillis, computeMillis, writeMillis, effectiveNodeCount
173 |
174 | // 15. 查看最小生成树,并过滤掉不相关的节点
175 | MATCH p=(a)-[r:MSTALL]->(b)
176 | WHERE NOT (b:公路站点 AND size((b) -[:MSTALL]-> ()) = 0)
177 | AND NOT (b:铁路站点 AND size((b) -[:MSTALL]-> ()) = 0)
178 | RETURN a,r,b
179 |
180 | // 16. 计算从一个城市出发随机游走到达其他城市
181 | // - 使用简单方式
182 | // - 游走200步,返回节点的访问次数
183 | MATCH (source:城市 {name: "北京"})
184 | CALL algo.randomWalk.stream(id(source), 200, 1)
185 | YIELD nodeIds
186 | UNWIND algo.getNodesById(nodeIds) AS place
187 | RETURN place.name AS place,count(place) AS count
188 | ORDER BY count DESC
189 |
190 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/README.md:
--------------------------------------------------------------------------------
1 | # 图数据库及图算法培训课程中使用的Cypher查询
2 |
3 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/实战-stackoverflow.txt:
--------------------------------------------------------------------------------
1 | // --------------------------------------------------------------
2 | //
3 | // 实战: Stackoverflow开放数据集分析
4 | //
5 | //
6 |
7 |
8 | // 1. 使用Neo4j IMPORT命令行导入数据
9 | //
10 | // 打开一个命令行窗口/终端窗口,进入Neo4j安装目录,运行下面的命令
11 |
12 | bin\neo4j-admin import --database=stackoverflow.graphdb --id-type=STRING --nodes:Post=".\import\stackoverflow\posts.csv" --nodes:User=".\import\stackoverflow\users.csv" --nodes:Tag=".\import\stackoverflow\tags.csv" --relationships:PARENT_OF=".\import\stackoverflow\posts_rel.csv" --relationships:ANSWER=".\import\stackoverflow\posts_answers.csv" --relationships:HAS_TAG=".\import\stackoverflow\tags_posts_rel.csv" --relationships:POSTED=".\import\stackoverflow\users_posts_rel.csv" --ignore-duplicate-nodes=true --ignore-missing-nodes=true
13 |
14 | // 2. 启动数据库、成功加载stakoverflow.graphdb后,运行下面的Cypher查询创建索引和限制。
15 | // 需要逐行复制并执行,不能批处理。
16 |
17 | CREATE INDEX ON :Post(title);
18 | CREATE INDEX ON :Post(createdAt);
19 | CREATE INDEX ON :Post(score);
20 | CREATE INDEX ON :Post(views);
21 | CREATE INDEX ON :Post(favorites);
22 | CREATE INDEX ON :Post(answers);
23 | CREATE INDEX ON :Post(score);
24 | CREATE INDEX ON :User(name);
25 | CREATE INDEX ON :User(createdAt);
26 | CREATE INDEX ON :User(reputation);
27 | CREATE INDEX ON :User(age);
28 | CREATE INDEX ON :Tag(count);
29 |
30 | CREATE CONSTRAINT ON (t:Tag) ASSERT t.tagId IS UNIQUE;
31 | CREATE CONSTRAINT ON (u:User) ASSERT u.userId IS UNIQUE;
32 | CREATE CONSTRAINT ON (p:Post) ASSERT p.postId IS UNIQUE;
33 |
34 | // 3. 统计标签和节点数
35 |
36 | MATCH (n:Post) WITH count(*) AS count RETURN 'Post' AS label, count
37 | UNION
38 | MATCH (t:Tag) WITH count(*) AS count RETURN 'Tag' AS label, count
39 | UNION
40 | MATCH (u:User) WITH count(*) AS count RETURN 'User' AS label, count
41 |
42 | // 4. 显示数据库模型
43 |
44 | CALL apoc.meta.graph
45 |
46 | // 5. 统计用户发帖次数的分布
47 |
48 | // 统计单位:N x 100次
49 | MATCH (u:User)
50 | WITH round(size ((u) -- ()) / 100) AS countOfPosts
51 | WITH countOfPosts, count(countOfPosts) AS cnt
52 | RETURN countOfPosts, cnt
53 | ORDER BY countOfPosts ASC
54 |
55 |
56 | // 6.1 根据(Post) -- (Tag) 之间的关系发现Tag之间的相关度
57 | // 创建新关系:(Tag) –[:SIMILAR_TO]-> (Tag)
58 | // - 关系的权重属性是Tag同时被Post引用的次数
59 | // - 关系的含义是无向的,因此只创建一次
60 | // - 使用apoc过程批量创建
61 |
62 | CALL apoc.periodic.iterate(
63 | "MATCH (n:Tag) WHERE n.count > 100 RETURN id(n) AS tid ORDER BY id(n) ASC;",
64 | "MATCH (t:Tag) WHERE id(t) = tid CALL apoc.path.expandConfig(t,{relationshipFilter:'HAS_TAG',labelFilter:'+Post|/Tag',uniqueness:'RELATIONSHIP_GLOBAL'}) YIELD path WITH t, nodes(path) AS nodes WITH t, nodes[2] AS node, count(*) AS cnt WHERE id(t) < id(node) AND node.count > 10 MERGE (t) -[r:SIMILAR_TO]-> (node) ON CREATE SET r.score = cnt",
65 | {batchSize:10, parallel:false,iterateList:true}
66 | )
67 |
68 | // 6.2 统计创建的新关系数
69 | MATCH (t:Tag) -[r:SIMILAR_TO]-> ()
70 | RETURN count(r)
71 |
72 | // 7.1 验证:SILIMAR_TO关系不存在双向关系(2个节点之间的环)
73 | MATCH path = (t1:Tag) -[:SIMILAR_TO]-> (t2:Tag) -[:SIMILAR_TO]-> (t1)
74 | RETURN path
75 |
76 | // 7.2 查看score值最大的SIMILAR_TO关系上所连接的Tag节点
77 |
78 | MATCH path = (:Tag) -[r:SIMILAR_TO]-> () RETURN path ORDER BY r.score DESC LIMIT 10
79 |
80 | // 8.1 根据SIMILAR_TO关系,分析主题的连通性
81 | CALL algo.unionFind.queue('Tag','SIMILAR_TO',{concurrency:4, write:true, partitionProperty:'componentSimTo'});
82 |
83 | // 8.2 创建新索引
84 | CREATE INDEX ON :Tag(componentSimTo)
85 |
86 | // 9.1 使用标签传播对Tag节点进行分组,不带权重
87 | CALL algo.labelPropagation('Tag', 'SIMILAR_TO',
88 | {iterations:10, writeProperty:'lpaPartitionOut', write:true, direction: 'OUTGOING'})
89 | YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, write, writeProperty;
90 |
91 | // 9.2 使用标签传播对Tag节点进行分组,考虑关系的带权重
92 | CALL algo.labelPropagation('Tag', 'SIMILAR_TO',
93 | {iterations:10, weightProperty:'score', writeProperty:'lpaPartitionOutWeighted', write:true, direction: 'OUTGOING'})
94 | YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, write, writeProperty;
95 |
96 |
97 | // 10.2 使用度中心性过程计算Tag节点的重要性
98 | CALL algo.degree('Tag', 'SIMILAR_TO'
99 | , {write: true, writeProperty:'degree',concurrency:4}
100 | )
101 | YIELD nodes,loadMillis,computeMillis,writeMillis,write, writeProperty
102 |
103 | // 10.2 查看结果
104 | MATCH (t:Tag)
105 | RETURN t.tagId, t.degree, count(t) AS cnt
106 | ORDER BY t.degree DESC LIMIT 10
107 |
108 | // 11.1 使用紧密中心性过程计算Tag节点的重要性
109 |
110 | CALL algo.closeness('Tag', 'SIMILAR_TO', {improved: true, writeProperty:'closeness',write:true})
111 | YIELD nodes,loadMillis,computeMillis,writeMillis
112 |
113 | // 11.2 查看结果
114 | MATCH (t:Tag) RETURN t.tagId, t.closeness, count(t) AS cnt
115 | ORDER BY t.closeness DESC LIMIT 10
116 |
117 |
118 | // 12.1 使用紧密中心性过程计算Tag节点的重要性
119 | CALL algo.pageRank('Tag', 'SIMILAR_TO’,
120 | {iterations:20, dampingFactor:0.85, write: true,
121 | writeProperty:"pagerank", weightProperty: "score"
122 | })
123 | YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, write, writeProperty
124 |
125 | // 12.2 查看结果
126 | MATCH (t:Tag) RETURN t.tagId, t.pagerank, count(t) AS cnt
127 | ORDER BY t.pagerank DESC LIMIT 10
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/cypher/实战-保险欺诈分析.txt:
--------------------------------------------------------------------------------
1 | // #####################################################
2 | //
3 | // 保险欺诈检测案例分析
4 | //
5 | // v1.0 by Fanghua Yu
6 |
7 | // ----------------------------------------
8 | // 1 - 图特征分析
9 |
10 | // 显示元数据
11 |
12 | CALL apoc.meta.graph
13 |
14 | // 投保人-投保次数分布
15 |
16 | MATCH (u:自然人)
17 | WITH size ((:索赔) -- (u)) AS countOfClaims
18 | WITH countOfClaims, count(countOfClaims) AS cnt
19 | RETURN countOfClaims, cnt
20 | ORDER BY countOfClaims ASC
21 |
22 | // -----------------------------------------
23 | // 2 - 合成身份检测
24 |
25 | // 发现`保险人`所有的相关节点
26 |
27 | MATCH (n:保险人)
28 | WITH n LIMIT 3
29 | MATCH path = (n)-[]->()
30 | RETURN path
31 |
32 | // 发现合成身份
33 | MATCH (n1:保险人)-[]->(contactInformation)
34 | WITH contactInformation, count(n1) AS RingSize,
35 | collect(id(n1)) AS _FraudRing
36 | WHERE RingSize > 1
37 | MATCH (contactInformation)<-[]-(n2:保险人),
38 | (n2)-[r:HAS_寿险|HAS_财产险|HAS_车辆险]->(insurance)
39 | WITH collect(id(n2)) AS AccountHolders ,
40 | contactInformation , RingSize , _FraudRing ,
41 | TOFLOAT(SUM(CASE type(r)
42 | WHEN 'HAS_寿险' THEN insurance.保额
43 | WHEN 'HAS_财产险' THEN insurance.保额
44 | ELSE 0 END)) as FinancialRisk
45 | RETURN _FraudRing, RingSize , FinancialRisk , collect(labels(contactInformation)) as ContactType
46 |
47 | // 查看潜在合成身份欺诈的关系图谱
48 | MATCH (n1:保险人)
49 | WHERE id(n1) IN [5000,5116]
50 | WITH n1
51 | MATCH path = (n1) -[]- (contactInformation)
52 | RETURN path
53 |
54 | // -----------------------------------------
55 | // 3 - 索赔相关分析
56 |
57 | // 查询索赔的关系图谱
58 | MATCH (n:索赔)
59 | WITH n LIMIT 3
60 | MATCH path = (n)-[]->()
61 | RETURN path
62 |
63 | // 创建人员之间新的关系LINKS
64 | MATCH (n1:索赔)-[r:HAS_车主]-> (o)
65 | MATCH (n1) -[:HAS_目击者]-> (w)
66 | MATCH (n1) -[:HAS_乘客]->(p)
67 | WITH n1,o,w,p
68 | MERGE (o) -[r1:LINKS{type:'目击者'}]-> (w)
69 | ON CREATE SET r1.times = 1
70 | ON MATCH SET r1.times = r1.times + 1
71 | MERGE (o) -[r2:LINKS{type: '乘客'}]-> (p)
72 | ON CREATE SET r2.times = 1
73 | ON MATCH SET r2.times = r2.times + 1
74 | RETURN *
75 |
76 | // 指定通用标签“自然人”
77 | MATCH (n:乘客) SET n:自然人
78 | MATCH (n:车主) SET n:自然人
79 | MATCH (n:目击者) SET n:自然人
80 |
81 | // 计算基于新关系的联通性
82 | CALL algo.unionFind.queue('自然人','LINKS')
83 |
84 | // 在分区partition属性上创建索引
85 | CREATE INDEX ON :自然人(partition)
86 |
87 | // 查看社区规模
88 | MATCH (n:自然人)
89 | RETURN n.partition, count(n) AS size
90 | ORDER BY size DESC LIMIT 10
91 |
92 | // 社团划分 - 标签传播
93 | CALL algo.labelPropagation(
94 | 'MATCH (n:自然人{partition:68}) RETURN id(n) AS id, 1 as weight, id(n) as value',
95 | 'MATCH (n1:自然人{partition:68}) -[f:LINKS]-> (n2:自然人) RETURN id(n1) as source, id(n2) as target, 1 as weight',
96 | { graph:'cypher',write:true,writeProperty:'lpPartition',iterations:20, diretion:'both' }
97 | );
98 |
99 | // 查看社区规模
100 | MATCH (n:自然人)
101 | WHERE exists(n.lpPartition)
102 | RETURN n.lpPartition, count(n) AS size
103 | ORDER BY size DESC LIMIT 10
104 |
105 | // 使用Lovain算法检测社团
106 |
107 | CALL algo.louvain(
108 | 'MATCH (n:自然人{partition:68}) RETURN id(n) AS id',
109 | 'MATCH (n1:自然人{partition:68}) -[f:LINKS]-> (n2:自然人) RETURN id(n1) as source, id(n2) as target, 1 as weight',
110 | {graph:'cypher',write:true,writeProperty:'lvPartition', diretion:'both'}
111 | );
112 |
113 | // 查看社区规模
114 | MATCH (n:自然人)
115 | WHERE exists(n.lvPartition)
116 | RETURN n.lvPartition, count(n) AS size
117 | ORDER BY size DESC LIMIT 10
118 |
119 | // 对Lovain算法划分的结果的前5名社团上色
120 |
121 | MATCH (n:自然人{partition:68})
122 | WHERE n.lvPartition IN [2,9,0,10,8]
123 | WITH id(n) AS nodeId, n.lvPartition AS partition
124 | CALL apoc.cypher.doIt('MATCH (n) WHERE id(n) = ' + nodeId + ' SET n:LvGroup_' + partition, NULL)
125 | YIELD value
126 | RETURN value
127 |
128 | // 查看上色结果
129 |
130 | MATCH (n:自然人{partition:68}) -[r:LINKS]-> (q:自然人)
131 | RETURN *
132 |
133 | // ------------------------------------------------------------
134 | // 4 - 人物重要性分析
135 |
136 | // 使用度中心性过程计算节点的重要性
137 |
138 | CALL algo.degree.stream('自然人', 'LINKS', {direction: 'BOTH', weightProperty: 'times'})
139 | YIELD nodeId, score
140 | RETURN algo.asNode(nodeId).姓名 AS node, score AS centrality
141 | ORDER BY centrality DESC
142 | LIMIT 20;
143 |
144 | // 使用紧密中心性过程计算节点的重要性
145 | CALL algo.closeness.stream(
146 | 'MATCH (n:自然人{partition:68}) RETURN id(n) AS id',
147 | 'MATCH (n1:自然人{partition:68}) -[f:LINKS]- (n2:自然人) RETURN id(n1) as source, id(n2) as target, 1 as weight',
148 | { graph:'cypher',write:true,writeProperty:'lvPartition’,diretion:'both' }
149 | ) YIELD nodeId, centrality
150 | RETURN algo.asNode(nodeId).姓名 AS node, centrality
151 | ORDER BY centrality DESC
152 | LIMIT 20;
153 |
154 | // 使用间接中心性过程计算节点的重要性
155 | CALL algo.betweenness.stream(
156 | 'MATCH (n:自然人{partition:68}) RETURN id(n) AS id',
157 | 'MATCH (n1:自然人{partition:68}) -[f:LINKS]- (n2:自然人) RETURN id(n1) as source, id(n2) as target, 1 as weight',
158 | {graph:'cypher',write:true,writeProperty:'lvPartition', diretion:'both'}
159 | ) YIELD nodeId, centrality
160 | RETURN algo.asNode(nodeId).姓名 AS node, centrality
161 | ORDER BY centrality DESC
162 | LIMIT 20;
163 |
164 | // 使用页面排行过程计算节点的重要性
165 | CALL algo.pageRank.stream(
166 | 'MATCH (n:自然人{partition:68}) RETURN id(n) AS id',
167 | 'MATCH (n1:自然人{partition:68}) -[f:LINKS]- (n2:自然人) RETURN id(n1) as source, id(n2) as target, 1 as weight',
168 | { graph:'cypher',write:true,writeProperty:'lvPartition’, diretion:'both' }
169 | ) YIELD nodeId, score
170 | RETURN algo.asNode(nodeId).姓名 AS node, score
171 | ORDER BY score DESC
172 | LIMIT 20;
173 |
174 | // ------------------------------------------------------------
175 | // 5 - 人物相似度分析
176 |
177 | // 使用重叠相似度过程计算相似节点
178 |
179 | MATCH (p1:自然人 {姓名: '冯小芳'}) -[:LINKS]- (p01)
180 | WITH p1, collect(id(p01)) AS p1s, count(p01) AS count
181 | WHERE count > 5
182 | MATCH (p2:自然人) -[:LINKS]- (p02) WHERE p1 <> p2
183 | WITH p1, p1s, p2, collect(id(p02)) AS p2s
184 | RETURN p1.姓名 AS from,
185 | p2.姓名 AS to,
186 | p1s,p2s,
187 | algo.similarity.overlap(p1s, p2s) AS similarity
188 | ORDER BY similarity DESC LIMIT 10
189 |
190 |
191 |
192 |
193 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/README.md:
--------------------------------------------------------------------------------
1 | # 培训教程中使用的测试数据
2 |
3 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/airlines.json:
--------------------------------------------------------------------------------
1 | {
2 | "1T": "Bulgarian Air Charter",
3 | "Q5": "40-Mile Air",
4 | "4O": "Interjet",
5 | "7A": "Express Air Cargo",
6 | "JY": "Air Turks and Caicos",
7 | "JU": "Air Serbia",
8 | "QH": "Kyrgyzstan",
9 | "A8": "Benin Golf Air",
10 | "RV": "Caspian Airlines",
11 | "1B": "Abacus International",
12 | "W9": "Eastwind Airlines",
13 | "6U": "Air Ukraine",
14 | "E4": "Aero Asia International",
15 | "ZI": "Aigle Azur",
16 | "AE": "Mandarin Airlines",
17 | "OZ": "Ozark Air Lines",
18 | "8U": "Afriqiyah Airways",
19 | "Q9": "Afrinat International Airlines",
20 | "KI": "Adam Air",
21 | "QB": "Georgian National Airlines",
22 | "LD": "Air Hong Kong",
23 | "UX": "Air Europa",
24 | "NX": "Air Macau",
25 | "ZV": "Air Midwest",
26 | "HM": "Air Seychelles",
27 | "AF": "Air France",
28 | "SB": "Air Caledonie International",
29 | "EH": "SAETA",
30 | "ZW": "Air Wisconsin",
31 | "GN": "Air Gabon",
32 | "NQ": "Air Japan",
33 | "VD": "SwedJet Airways",
34 | "TT": "Tigerair Australia",
35 | "4N": "Air North Charter - Canada",
36 | "NZ": "Eagle Airways",
37 | "QM": "Air Malawi",
38 | "ML": "Midway Airlines (1976–1991)",
39 | "P8": "Pantanal Linhas Aéreas",
40 | "BM": "BMI Regional",
41 | "ZX": "Air Georgian",
42 | "G8": "Gujarat Airways",
43 | "7T": "Tobruk Air",
44 | "6V": "Mars RK",
45 | "NH": "All Nippon Airways",
46 | "TZ": "ATA Airlines",
47 | "2Q": "Air Cargo Carriers",
48 | "V7": "Volotea",
49 | "AB": "Air Berlin",
50 | "4D": "Air Sinai",
51 | "QN": "Air Armenia",
52 | "AI": "Air India Limited",
53 | "PJ": "Air Saint Pierre",
54 | "SZ": "Air Southwest",
55 | "8C": "Shanxi Airlines",
56 | "NF": "Air Vanuatu",
57 | "ZB": "Monarch Airlines",
58 | "CC": "Macair Airlines",
59 | "RB": "Syrian Arab Airlines",
60 | "TN": "Air Tahiti Nui",
61 | "SW": "Air Namibia",
62 | "AW": "Dirgantara Air Service",
63 | "PE": "People's Viennaline",
64 | "JM": "Jetstar Hong Kong Airways",
65 | "6G": "Air Wales",
66 | "TX": "Transportes Aéreos Nacionales",
67 | "IX": "Air India Express",
68 | "BT": "Air Baltic",
69 | "EL": "Ellinair",
70 | "YW": "Air Nostrum",
71 | "PX": "Air Niugini",
72 | "G9": "Air Arabia",
73 | "AC": "Air Canada",
74 | "AP": "Air One",
75 | "XT": "SkyStar Airways",
76 | "UM": "Air Zimbabwe",
77 | "S2": "Air Sahara",
78 | "TC": "Air Tanzania",
79 | "2J": "Air Burkina",
80 | "KM": "Air Malta",
81 | "YT": "Air Togo",
82 | "G4": "Allegiant Air",
83 | "M3": "North Flying",
84 | "O4": "Antrak Air",
85 | "GB": "ABX Air",
86 | "8V": "Wright Air Service",
87 | "8T": "Air Tindi",
88 | "JP": "Adria Airways",
89 | "A3": "Aegean Airlines",
90 | "2K": "Aerogal",
91 | "KD": "KD Avia",
92 | "KO": "Alaska Central Express",
93 | "VX": "Virgin America",
94 | "KH": "Aloha Air Cargo",
95 | "AA": "American Airlines",
96 | "AX": "Trans States Airlines",
97 | "AN": "Ansett Australia",
98 | "5W": "Astraeus",
99 | "VV": "Aerosvit Airlines",
100 | "WK": "Edelweiss Air",
101 | "QQ": "Reno Air",
102 | "FG": "Ariana Afghan Airlines",
103 | "Y2": "Flyglobespan",
104 | "SU": "Aeroflot Russian Airlines",
105 | "5Z": "VivaColombia",
106 | "5D": "DonbassAero",
107 | "1A": "Amadeus IT Group",
108 | "JJ": "LATAM Brasil",
109 | "PL": "Airstars",
110 | "8A": "Atlas Blue",
111 | "GD": "Air Alpha Greenland",
112 | "HT": "Aeromist-Kharkiv",
113 | "J2": "Azerbaijan Airlines",
114 | "U3": "Avies",
115 | "4Y": "Yute Air Alaska",
116 | "5A": "Alpine Air Express",
117 | "W4": "Aero Services Executive",
118 | "IZ": "Arkia Israel Airlines",
119 | "M6": "Amerijet International",
120 | "4A": "Air Kiribati",
121 | "EV": "ExpressJet",
122 | "HP": "Phoenix Airways",
123 | "VH": "Aeropostal Alas de Venezuela",
124 | "AM": "Aeroméxico",
125 | "TL": "Trans Mediterranean Airlines",
126 | "OY": "Omni Air International",
127 | "IW": "Wings Air",
128 | "J6": "AVCOM",
129 | "2D": "Aero VIP",
130 | "VB": "VIVA Aerobus",
131 | "OE": "Asia Overnight Express",
132 | "GV": "Aero Flight",
133 | "JW": "Vanilla Air",
134 | "2B": "Aerocondor",
135 | "4C": "Aires, Aerovías de Integración Regional, S.A.",
136 | "AR": "Aerolíneas Argentinas",
137 | "AS": "Alaska Airlines, Inc.",
138 | "OB": "Oasis International Airlines",
139 | "HC": "Iceland Express",
140 | "FO": "Airlines of Tasmania",
141 | "OS": "Austrian Airlines",
142 | "IQ": "Augsburg Airways",
143 | "RU": "SkyKing Turks and Caicos Airways",
144 | "MO": "Calm Air",
145 | "GR": "Gemini Air Cargo",
146 | "NO": "Neos",
147 | "AU": "Austral Líneas Aéreas",
148 | "AO": "Australian Airlines",
149 | "AV": "Avianca - Aerovías del Continente Americano S.A.",
150 | "A0": "Avianca Argentina",
151 | "O6": "Avianca Brazil",
152 | "K8": "Airlink Zambia",
153 | "B9": "Air Bangladesh",
154 | "HJ": "Hellas Jet",
155 | "AK": "Air Bridge Carriers",
156 | "D7": "FlyAsianXpress",
157 | "DJ": "Polynesian Blue",
158 | "I5": "AirAsia India",
159 | "EX": "Air Santo Domingo",
160 | "3G": "Atlant-Soyuz Airlines",
161 | "AZ": "Alitalia",
162 | "ZE": "Líneas Aéreas Azteca",
163 | "A2": "Cielos Airlines",
164 | "R7": "Aserca Airlines",
165 | "RX": "Aviaexpress",
166 | "MQ": "American Eagle Airlines",
167 | "ZS": "Sama Airlines",
168 | "FF": "Airshop",
169 | "VU": "Air Ivoire",
170 | "BP": "Air Botswana",
171 | "GS": "Tianjin Airlines",
172 | "VT": "Air Tahiti",
173 | "3N": "Air Urga",
174 | "VL": "Air VIA",
175 | "FK": "Keewatin Air",
176 | "G2": "Avirex",
177 | "V8": "Iliamna Air Taxi",
178 | "K6": "Khalifa Airways",
179 | "VE": "C.A.I. Second",
180 | "V5": "Royal Aruban Airlines",
181 | "CA": "Air China",
182 | "Q6": "Aero Condor Peru",
183 | "5F": "Fly One",
184 | "QC": "Air Corridor",
185 | "NV": "Air Central",
186 | "CV": "Cargolux",
187 | "CW": "Air Marshall Islands",
188 | "ZA": "Interavia Airlines",
189 | "AH": "Air Algérie",
190 | "ER": "Astar Air Cargo",
191 | "HO": "Juneyao Airlines",
192 | "EN": "Air Dolomiti",
193 | "NM": "Mount Cook Airlines",
194 | "EE": "Aero Airlines",
195 | "4F": "Air City",
196 | "EI": "Aer Lingus",
197 | "E8": "Alpi Eagles",
198 | "KY": "Air São Tomé and Príncipe",
199 | "PC": "Pegasus Airlines",
200 | "OF": "Transports et Travaux Aériens de Madagascar",
201 | "FJ": "Fiji Airways",
202 | "RC": "Atlantic Airways",
203 | "NY": "Air Iceland",
204 | "2P": "Air Philippines",
205 | "2U": "Air Guinee Express",
206 | "0A": "Amber Air",
207 | "DA": "Air Georgia",
208 | "GL": "Miami Air International",
209 | "LL": "Allegro",
210 | "5Y": "Atlas Air",
211 | "GG": "Cargo 360",
212 | "H9": "Izair",
213 | "HD": "AIRDO",
214 | "IP": "Atyrau Air Ways",
215 | "QK": "Air Canada Jazz",
216 | "KK": "Atlasjet",
217 | "JS": "Air Koryo",
218 | "KC": "Air Astana",
219 | "LV": "Albanian Airlines",
220 | "3S": "Air Guyane Express",
221 | "D4": "Alidaunia",
222 | "9I": "Thai Sky Airlines",
223 | "XL": "Aerolane",
224 | "A6": "Hongtu Airlines",
225 | "TD": "Tulip Air",
226 | "L8": "Air Luxor GB",
227 | "LK": "Air Luxor",
228 | "MK": "Air Mauritius",
229 | "MD": "Air Madagascar",
230 | "9U": "Air Moldova",
231 | "L9": "Teamline Air",
232 | "A7": "Air Plus Comet",
233 | "QO": "Origin Pacific Airways",
234 | "MR": "Air Mauritanie",
235 | "F4": "Albarka Air",
236 | "AJ": "Aero Contractors",
237 | "8Y": "China Postal Airlines",
238 | "OT": "Aeropelican Air Services",
239 | "AD": "Azul Linhas Aéreas Brasileiras",
240 | "QD": "Air Class Líneas Aéreas",
241 | "QS": "Travel Service",
242 | "AG": "",
243 | "MC": "Air Mobility Command",
244 | "RE": "Stobart Air",
245 | "UU": "Air Austral",
246 | "ZP": "Silk Way Airlines",
247 | "6K": "Asian Spirit",
248 | "A5": "Hop!",
249 | "QL": "Línea Aérea de Servicio Ejecutivo Regional",
250 | "R3": "Yakutia Airlines",
251 | "MV": "Armenian International Airways",
252 | "2O": "Air Salone",
253 | "U8": "Armavia",
254 | "BQ": "Baltia Air Lines",
255 | "P5": "AeroRepública",
256 | "BF": "Bluebird Cargo",
257 | "5L": "AeroSur",
258 | "JR": "Aero California",
259 | "Z3": "Avient Aviation",
260 | "GM": "Air Slovakia",
261 | "VW": "Aeromar",
262 | "OR": "TUI Airlines Netherlands",
263 | "CG": "Airlines PNG",
264 | "TY": "Iberworld",
265 | "FL": "AirTran Airways",
266 | "TS": "Air Transat",
267 | "EC": "Avialeasing Aviation Company",
268 | "DW": "Aero-Charter Ukraine",
269 | "U7": "USA Jet Airlines",
270 | "6R": "Alrosa Air Company",
271 | "6A": "Aviacsa",
272 | "JZ": "Skyways Express",
273 | "AQ": "MAP-Management and Planung",
274 | "3J": "Zip",
275 | "SM": "Swedline Express",
276 | "KJ": "British Mediterranean Airways",
277 | "BX": "Coast Air",
278 | "YE": "Aryan Cargo Express",
279 | "VJ": "Vietjet Air",
280 | "3O": "Air Arabia Maroc",
281 | "X9": "Avion Express",
282 | "JD": "Beijing Capital Airlines",
283 | "ID": "Interlink Airlines",
284 | "BA": "British Airways",
285 | "BG": "Biman Bangladesh Airlines",
286 | "B4": "Bankair",
287 | "WX": "CityJet",
288 | "BZ": "Keystone Air Service",
289 | "JA": "JetSMART",
290 | "J4": "Jordan International Air Cargo",
291 | "8H": "BH Air",
292 | "4T": "Belair Airlines",
293 | "UP": "Bahamasair",
294 | "E6": "Bringer Air Cargo Taxi Aéreo",
295 | "LZ": "Balkan Bulgarian Airlines",
296 | "TH": "Transmile Air Services",
297 | "BS": "British International Helicopters",
298 | "PG": "Bangkok Airways",
299 | "KF": "Blue1",
300 | "JV": "Bearskin Lake Air Service",
301 | "B3": "Bellview Airlines",
302 | "BD": "BMI",
303 | "WW": "WOW air",
304 | "CH": "Bemidji Airlines",
305 | "BO": "Bouraq Indonesia Airlines",
306 | "BV": "Blue Panorama Airlines",
307 | "7R": "BRA-Transportes Aéreos",
308 | "8E": "Bering Air",
309 | "B2": "Belavia Belarusian Airlines",
310 | "BN": "Horizon Airlines",
311 | "GQ": "Big Sky Airlines",
312 | "V9": "Star1 Airlines",
313 | "Y6": "Batavia Air",
314 | "BU": "Buryat Airlines Aircompany",
315 | "J8": "Berjaya Air",
316 | "QW": "Blue Wings",
317 | "SN": "Brussels Airlines",
318 | "DB": "Brit Air",
319 | "E9": "Boston-Maine Airways",
320 | "NT": "Binter Canarias",
321 | "0B": "Blue Air",
322 | "FB": "Bulgaria Air",
323 | "8N": "Barents AirLink",
324 | "CJ": "CityFlyer Express",
325 | "YB": "Borajet",
326 | "BW": "Caribbean Airlines",
327 | "7N": "PAWA Dominicana",
328 | "5C": "CAL Cargo Air Lines",
329 | "3C": "RegionsAir",
330 | "R9": "Camai Air",
331 | "UY": "Cameroon Airlines",
332 | "C6": "CanJet",
333 | "CP": "Compass Airlines",
334 | "5T": "Canadian North",
335 | "W2": "Canadian Western Airlines",
336 | "9K": "Cape Air",
337 | "PT": "West Air Sweden",
338 | "2G": "Cargoitalia",
339 | "W8": "Cargojet Airways",
340 | "C8": "Chicago Express Airlines",
341 | "8B": "Caribbean Star Airlines",
342 | "V3": "Carpatair",
343 | "CX": "Cathay Pacific",
344 | "KX": "Cayman Airways",
345 | "5J": "Cebu Pacific",
346 | "3B": "Central Connect Airlines",
347 | "9M": "Central Mountain Air",
348 | "J7": "ValuJet Airlines",
349 | "WE": "Thai Smile Airways",
350 | "OP": "Chalk's International Airlines",
351 | "MG": "Champion Air",
352 | "2Z": "Chang An Airlines",
353 | "S8": "Skywise Airline",
354 | "CI": "China Airlines",
355 | "CK": "China Cargo Airlines",
356 | "MU": "China Eastern Airlines",
357 | "G5": "China Express Airlines",
358 | "WH": "WebJet Linhas Aéreas",
359 | "CZ": "China Southern Airlines",
360 | "KN": "China United Airlines",
361 | "XO": "LTE International Airways",
362 | "3Q": "China Yunnan Airlines",
363 | "X7": "Chitaavia",
364 | "QI": "Cimber Sterling",
365 | "C7": "Rico Linhas Aéreas",
366 | "C9": "Cirrus Airlines",
367 | "CF": "City Airline",
368 | "G3": "Gol Transportes Aéreos",
369 | "CT": "Civil Air Transport",
370 | "6P": "Club Air",
371 | "DQ": "Coastal Air",
372 | "9L": "Colgan Air",
373 | "YD": "Cologne Air Transport GmbH",
374 | "OH": "PSA Airlines",
375 | "MN": "Comair",
376 | "C5": "CommutAir",
377 | "KR": "Comores Airlines",
378 | "GJ": "Eurofly",
379 | "DE": "Condor Flugdienst",
380 | "CO": "Continental Express",
381 | "CS": "Continental Micronesia",
382 | "V0": "Conviasa",
383 | "CM": "Copa Airlines",
384 | "CQ": "Sunshine Express Airlines",
385 | "XC": "Corendon Airlines",
386 | "CD": "Corendon Dutch Airlines",
387 | "SS": "Corsairfly",
388 | "XK": "Corse Méditerranée",
389 | "F5": "Cosmic Air",
390 | "OU": "Croatia Airlines",
391 | "7C": "Jeju Air",
392 | "QE": "Crossair Europe",
393 | "CU": "Cubana de Aviación",
394 | "CY": "Cyprus Airways",
395 | "YK": "Cyprus Turkish Airlines",
396 | "OK": "Czech Airlines",
397 | "8L": "Redhill Aviation",
398 | "XG": "Clickair",
399 | "WD": "WDL Aviation",
400 | "DX": "DAT Danish Air Transport",
401 | "ES": "DHL International",
402 | "L3": "LTU Austria",
403 | "D3": "Daallo Airlines",
404 | "N2": "Kabo Air",
405 | "H8": "Dalavia",
406 | "0D": "Darwin Airline",
407 | "D5": "Dauair",
408 | "DL": "Delta Air Lines",
409 | "2A": "Deutsche Bahn",
410 | "1I": "Sky Trek International Airlines",
411 | "DH": "Independence Air",
412 | "Z6": "Dniproavia",
413 | "YU": "Dominair",
414 | "DO": "Dominicana de Aviación",
415 | "E3": "Domodedovo Airlines",
416 | "D9": "Donavia",
417 | "KA": "Dragonair, Hong Kong Dragon Airlines",
418 | "KB": "Druk Air",
419 | "DI": "Dba",
420 | "9A": "Eagle Express Air Charter",
421 | "E1": "Everbread",
422 | "1C": "Electronic Data Systems",
423 | "1Y": "Electronic Data Systems",
424 | "BR": "EVA Air",
425 | "EY": "Etihad Airways",
426 | "H7": "Eagle Air",
427 | "QU": "Uganda Airlines",
428 | "S9": "East African Safari Air",
429 | "EA": "European Air Express",
430 | "T3": "Eastern Airways",
431 | "QF": "Sunstate Airlines",
432 | "DK": "Eastland Air",
433 | "MS": "Egyptair",
434 | "LY": "El Al Israel Airlines",
435 | "UZ": "El-Buraq Air Transport",
436 | "EK": "Emirates Airlines",
437 | "EM": "Empire Airlines",
438 | "EU": "Empresa Ecuatoriana De Aviación",
439 | "E0": "Eos Airlines",
440 | "B8": "Eritrean Airlines",
441 | "E7": "European Aviation Air Charter",
442 | "OV": "SalamAir",
443 | "ET": "Ethiopian Airlines",
444 | "RZ": "Euro Exec Express",
445 | "MM": "SAM Colombia",
446 | "UI": "Eurocypria Airlines",
447 | "K2": "Eurolot",
448 | "3W": "Euromanx Airways",
449 | "5O": "Europe Airpost",
450 | "QY": "European Air Transport",
451 | "EW": "Eurowings",
452 | "EZ": "Sun Air of Scandinavia",
453 | "JN": "Excel Airways",
454 | "MB": "MNG Airlines",
455 | "OW": "Executive Airlines",
456 | "EO": "Hewa Bora Airways",
457 | "U2": "United Feeder Service",
458 | "DS": "easyJet Switzerland",
459 | "IH": "Irtysh Air",
460 | "EF": "Far Eastern Air Transport",
461 | "FD": "Thai AirAsia",
462 | "F6": "FaroeJet",
463 | "F3": "Faso Airways",
464 | "FX": "Federal Express",
465 | "N8": "National Air Cargo dba National Airlines",
466 | "4S": "Finalair Congo",
467 | "AY": "Finnair",
468 | "FC": "Finncomm Airlines",
469 | "FY": "Northwest Regional Airlines",
470 | "7F": "First Air",
471 | "DP": "First Choice Airways",
472 | "8F": "Fischer Air",
473 | "8D": "Servant Air",
474 | "B5": "Flightline",
475 | "PA": "Pan American World Airways",
476 | "RF": "Florida West International Airways",
477 | "F2": "Fly Air",
478 | "OJ": "Overland Airways",
479 | "SH": "Fly Me Sweden",
480 | "TE": "Skytaxi",
481 | "LF": "FlyNordic",
482 | "F7": "Flybaboo",
483 | "BE": "Flybe",
484 | "W3": "Switfair Cargo",
485 | "VY": "Vueling Airlines",
486 | "HK": "Four Star Aviation / Four Star Cargo",
487 | "FH": "Futura International Airways",
488 | "SJ": "Freedom Air",
489 | "FP": "Servicios Aéreos de los Andes",
490 | "F9": "Frontier Airlines",
491 | "2F": "Frontier Flying Service",
492 | "FZ": "Flydubai",
493 | "9Y": "Fly Georgia",
494 | "VK": "Virgin Nigeria Airways",
495 | "GX": "Pacificair",
496 | "Y5": "Pace Airlines",
497 | "GT": "GB Airways",
498 | "Z5": "GMG Airlines",
499 | "7O": "Galaxy Air",
500 | "1G": "Galileo International",
501 | "GC": "Gambia International Airlines",
502 | "G7": "GoJet Airlines",
503 | "GA": "Garuda Indonesia",
504 | "4G": "Gazpromavia",
505 | "A9": "Georgian Airways",
506 | "ST": "Germania",
507 | "4U": "Germanwings",
508 | "GP": "Palau Trans Pacific Airlines",
509 | "GH": "Ghana Airways",
510 | "G0": "Ghana International Airlines",
511 | "GK": "JetStar Japan",
512 | "DC": "Golden Air",
513 | "G1": "Gorkha Airlines",
514 | "ZK": "Great Lakes Airlines",
515 | "IJ": "Spring Airlines Japan",
516 | "G6": "Air Volga",
517 | "J9": "Jazeera Airways",
518 | "GF": "Gulf Air Bahrain",
519 | "GY": "Tri-MG Intra Asia Airlines",
520 | "H6": "Hageland Aviation Services",
521 | "HR": "Hahn Air",
522 | "HU": "Hainan Airlines",
523 | "1R": "Hainan Phoenix Information Systems",
524 | "2T": "Haiti Ambassador Airlines",
525 | "4R": "Hamburg International",
526 | "X3": "Hapag-Lloyd Express (TUIfly)",
527 | "HF": "Hapagfly",
528 | "HB": "Harbor Airlines",
529 | "HQ": "Thomas Cook Airlines",
530 | "HA": "Hawaiian Airlines",
531 | "BH": "Hawkair",
532 | "HN": "Heavylift Cargo Airlines",
533 | "JB": "Helijet",
534 | "ZU": "Helios Airways",
535 | "HW": "North-Wright Airways",
536 | "2L": "Helvetic Airways",
537 | "UD": "Hex'Air",
538 | "5K": "Hi Fly",
539 | "H5": "Mavial Magadan Airlines",
540 | "HX": "Hong Kong Airlines",
541 | "RH": "Republic Express Airlines",
542 | "UO": "Hong Kong Express Airways",
543 | "HH": "Hope Air",
544 | "QX": "Horizon Air",
545 | "H4": "Inter Island Airways",
546 | "IK": "Lankair",
547 | "II": "IBC Airways",
548 | "0C": "IBL Aviation",
549 | "C3": "Independent Carrier (ICAR)",
550 | "1F": "INFINI Travel Information",
551 | "1U": "Polyot Sirena",
552 | "IB": "Iberia Airlines",
553 | "I2": "Iberia Express",
554 | "FW": "Ibex Airlines",
555 | "FI": "Icelandair",
556 | "6E": "IndiGo Airlines",
557 | "IC": "Indian Airlines",
558 | "I9": "Indigo Airlines",
559 | "QZ": "Indonesia AirAsia",
560 | "IO": "Indonesian Airlines",
561 | "D6": "Interair South Africa",
562 | "RS": "Sky Regional Airlines",
563 | "6I": "International Business Air",
564 | "3L": "Intersky",
565 | "I4": "Interstate Airlines",
566 | "IR": "Iran Air",
567 | "EP": "Iran Aseman Airlines",
568 | "IA": "Iraqi Airways",
569 | "2S": "Satgur Air Transport",
570 | "CN": "Westward Airways",
571 | "IF": "Islas Airways",
572 | "WC": "Islena De Inversiones",
573 | "6H": "Israir",
574 | "FS": "Servicios de Transportes Aéreos Fueguinos",
575 | "GI": "Itek Air",
576 | "XM": "J-Air",
577 | "JC": "JAL Express",
578 | "JO": "Jettime",
579 | "MT": "Thomas Cook Airlines",
580 | "1M": "JSC Transport Automated Information Systems",
581 | "JI": "Midway Airlines (1993–2003)",
582 | "3X": "Japan Air Commuter",
583 | "JL": "Japan Airlines Domestic",
584 | "EG": "Japan Asia Airways",
585 | "NU": "Japan Transocean Air",
586 | "O2": "Linear Air",
587 | "9W": "Jet Airways",
588 | "QJ": "Jet Airways",
589 | "PP": "Jet Aviation",
590 | "3K": "Jetstar Asia Airways",
591 | "LS": "Jet2.com",
592 | "B6": "JetBlue Airways",
593 | "JF": "L.A.B. Flying Service",
594 | "0J": "Jetclub",
595 | "SG": "Spicejet",
596 | "JQ": "Jetstar Airways",
597 | "JX": "Jett8 Airlines Cargo",
598 | "R5": "Malta Air Charter",
599 | "6J": "Skynet Asia Airways",
600 | "KW": "Wataniya Airways",
601 | "WA": "Western Airlines",
602 | "KL": "KLM",
603 | "K4": "Kalitta Air",
604 | "K9": "Krylo Airlines",
605 | "RQ": "Kam Air",
606 | "E2": "Rio Grande Air",
607 | "V2": "Vision Airlines",
608 | "KV": "Kavminvodyavia",
609 | "M5": "Kenmore Air",
610 | "KQ": "Kenya Airways",
611 | "IT": "Tigerair Taiwan",
612 | "Y9": "Kish Air",
613 | "KP": "Kiwi International Air Lines",
614 | "7K": "Kogalymavia Air Company",
615 | "8J": "Komiinteravia",
616 | "KE": "Korean Air",
617 | "7B": "Krasnojarsky Airlines",
618 | "GW": "SkyGreece Airlines",
619 | "KU": "Kuwait Airways",
620 | "GO": "Kuzu Airlines Cargo",
621 | "N5": "Skagway Air Service",
622 | "R8": "Kyrgyzstan Airlines",
623 | "YQ": "TAR Aerolineas",
624 | "LR": "LACSA",
625 | "KG": "LAI - Línea Aérea IAACA",
626 | "LA": "LATAM Chile",
627 | "4M": "LATAM Argentina",
628 | "PZ": "TAM Mercosur",
629 | "LU": "LATAM Express",
630 | "LP": "LATAM Peru",
631 | "NI": "Portugalia",
632 | "L5": "Lufttransport",
633 | "LO": "LOT Polish Airlines",
634 | "LT": "LongJiang Airlines",
635 | "N6": "Nuevo Continente",
636 | "QV": "Lao Airlines",
637 | "L7": "Línea Aérea SAPSA",
638 | "NG": "Lauda Air",
639 | "LQ": "Lebanese Air Transport",
640 | "LI": "Leeward Islands Air Transport",
641 | "LN": "Libyan Arab Airlines",
642 | "TM": "Linhas Aéreas de Moçambique",
643 | "JT": "Lion Mentari Airlines",
644 | "LM": "Livingston",
645 | "LB": "Lloyd Aéreo Boliviano",
646 | "LC": "Varig Logística",
647 | "HE": "Luftfahrtgesellschaft Walter",
648 | "LH": "Lufthansa Cargo",
649 | "CL": "Lufthansa CityLine",
650 | "L1": "Lufthansa Systems",
651 | "DV": "Nantucket Airlines",
652 | "LG": "Luxair",
653 | "5V": "Lviv Airlines",
654 | "L2": "Lynden Air Cargo",
655 | "L4": "Lynx Aviation",
656 | "Z8": "Línea Aérea Amaszonas",
657 | "MJ": "Mihin Lanka",
658 | "Q2": "Maldivian (airline)",
659 | "OD": "Malindo Airways",
660 | "M7": "Tropical Airways",
661 | "MH": "Malaysia Airlines",
662 | "IN": "NAM Air",
663 | "OM": "MIAT Mongolian Airlines",
664 | "DM": "Maersk",
665 | "W5": "Mahan Air",
666 | "M2": "MHS Aviation GmbH",
667 | "TF": "Malmö Aviation",
668 | "MA": "Malév Hungarian Airlines",
669 | "RI": "Mandala Airlines",
670 | "JE": "Mango",
671 | "MP": "Martinair",
672 | "Q4": "Starlink Aviation",
673 | "8M": "Myanmar Airways International",
674 | "MY": "Midwest Airlines (Egypt)",
675 | "MW": "Mokulele Airlines",
676 | "7M": "Mayair",
677 | "M8": "Mekong Airlines",
678 | "IM": "Menajet",
679 | "IG": "Meridiana",
680 | "MZ": "Merpati Nusantara Airlines",
681 | "YV": "Mesa Airlines",
682 | "XJ": "Thai AirAsia X",
683 | "MX": "Mexicana de Aviación",
684 | "ME": "Middle East Airlines",
685 | "YX": "Midwest Airlines",
686 | "M4": "Mistral Air",
687 | "2M": "Moldavian Airlines",
688 | "8I": "Myway Airlines",
689 | "YM": "Montenegro Airlines",
690 | "5M": "Sibaviatrans",
691 | "3R": "Moskovia Airlines",
692 | "M9": "Motor Sich",
693 | "N4": "Nordwind Airlines",
694 | "VZ": "Thai Vietjet Air",
695 | "UB": "Myanma Airways",
696 | "6N": "Nordic Regional",
697 | "P9": "Peruvian Airlines",
698 | "UE": "Transeuropean Airlines",
699 | "N7": "National Airlines",
700 | "NA": "North American Airlines",
701 | "9O": "National Airways Cameroon",
702 | "NC": "Northern Air Cargo",
703 | "CE": "Nationwide Airlines",
704 | "1N": "Navitaire",
705 | "RA": "Nepal Airlines",
706 | "EJ": "New England Airlines",
707 | "2N": "Yuzhmashavia",
708 | "HG": "Niki",
709 | "KZ": "Nippon Cargo Airlines",
710 | "DD": "Nok Air",
711 | "5N": "Nordavia",
712 | "JH": "Nordeste Linhas Aéreas Regionais",
713 | "N9": "North Coast Aviation",
714 | "NW": "Northwest Airlines",
715 | "J3": "Northwestern Air",
716 | "DY": "Norwegian Air Shuttle",
717 | "D8": "Norwegian Air International",
718 | "DU": "Norwegian Long Haul",
719 | "BJ": "Nouvel Air Tunisie",
720 | "O9": "Nova Airline",
721 | "VQ": "Novo Air",
722 | "NK": "Spirit Airlines",
723 | "UQ": "O'Connor Airlines",
724 | "O8": "Oasis Hong Kong Airlines",
725 | "VC": "Voyageur Airways",
726 | "OA": "Olympic Airlines",
727 | "WY": "Oman Air",
728 | "8Q": "Princess Air",
729 | "R2": "Orenburg Airlines",
730 | "OX": "Orient Thai Airlines",
731 | "OL": "OLT Express Germany",
732 | "ON": "Our Airline",
733 | "O7": "Ozjet Airlines",
734 | "PV": "St Barth Commuter",
735 | "9Q": "PB Air",
736 | "PU": "PLUNA",
737 | "U4": "PMTair",
738 | "BL": "Pacific Airlines",
739 | "8P": "Pacific Coastal Airlines",
740 | "Q8": "Pacific East Asia Cargo Airlines",
741 | "LW": "Sun Air International",
742 | "PK": "Pakistan International Airlines",
743 | "PF": "Palestinian Airlines",
744 | "NR": "Pamir Airways",
745 | "PN": "Pan American Airways",
746 | "I7": "Paramount Airways",
747 | "P3": "Passaredo Transportes Aéreos",
748 | "KS": "Peninsula Airways",
749 | "Z2": "EZD",
750 | "PR": "Philippine Airlines",
751 | "9R": "Phuket Air",
752 | "PI": "Sun Air (Fiji)",
753 | "9E": "Pinnacle Airlines",
754 | "PO": "Polar Air Cargo",
755 | "PH": "Polynesian Airlines",
756 | "PD": "Porter Airlines",
757 | "BK": "Potomac Air",
758 | "PW": "Precision Air",
759 | "TO": "Transavia France",
760 | "FE": "Primaris Airlines",
761 | "8W": "Private Wings Flugcharter",
762 | "P6": "Privilege Style Líneas Aéreas",
763 | "P0": "Proflight Zambia",
764 | "FV": "Rossiya",
765 | "QR": "Qatar Airways",
766 | "R6": "RACSA",
767 | "1D": "Radixx Solutions International",
768 | "V4": "Vieques Air Link",
769 | "FN": "Regional Air Lines",
770 | "ZL": "Regional Express",
771 | "P7": "Russian Sky Airlines",
772 | "RW": "Republic Airlines",
773 | "RL": "Royal Phnom Penh Airways",
774 | "SL": "Thai Lion Mentari",
775 | "GZ": "Air Rarotonga",
776 | "RR": "Royal Air Force",
777 | "AT": "Royal Air Maroc",
778 | "R0": "Royal Airlines",
779 | "BI": "Royal Brunei Airlines",
780 | "RJ": "Royal Jordanian",
781 | "RK": "Royal Khmer Airlines",
782 | "WR": "WestJet Encore",
783 | "WB": "Rwandair Express",
784 | "7S": "Ryan Air Service",
785 | "RD": "Ryan International Airlines",
786 | "FR": "Ryanair",
787 | "YS": "Régional Compagnie Aérienne Européenne",
788 | "TR": "Tigerair Singapore",
789 | "6Y": "Smartlynx Airlines",
790 | "7E": "Sylt Air GmbH",
791 | "S4": "SATA International",
792 | "SA": "South African Airways",
793 | "W7": "Western Pacific Airlines",
794 | "NL": "Shaheen Air International",
795 | "SK": "SAS Braathens",
796 | "UG": "Tuninter",
797 | "S7": "S7 Airlines",
798 | "BB": "Seaborne Airlines",
799 | "K5": "SeaPort Airlines",
800 | "UL": "SriLankan Airlines",
801 | "SY": "Sun Country Airlines",
802 | "I6": "Sky Eyes",
803 | "7G": "Star Flyer",
804 | "FA": "Safair",
805 | "HZ": "Sat Airlines",
806 | "SP": "SATA Air Acores",
807 | "8S": "Scorpio Aviation",
808 | "ZY": "Sky Airlines",
809 | "SQ": "Singapore Airlines Cargo",
810 | "SI": "Skynet Airlines",
811 | "XS": "SITA",
812 | "FT": "Siem Reap Airways",
813 | "SX": "Skybus Airlines",
814 | "S6": "Star Air",
815 | "D2": "Severstal Air Company",
816 | "5G": "Skyservice Airlines",
817 | "SD": "Sudan Airways",
818 | "SV": "Saudia",
819 | "WN": "Southwest Airlines",
820 | "A4": "Southern Winds Airlines",
821 | "WG": "Sunwing Airlines",
822 | "LX": "Swiss International Air Lines",
823 | "SR": "Swissair",
824 | "WV": "Swe Fly",
825 | "XQ": "SunExpress",
826 | "AL": "TransAVIAexport Airlines",
827 | "E5": "Samara Airlines",
828 | "SC": "Shandong Airlines",
829 | "9C": "Spring Airlines",
830 | "3U": "Sichuan Airlines",
831 | "FM": "Shanghai Airlines",
832 | "ZH": "Shenzhen Airlines",
833 | "7L": "Sun D'Or",
834 | "NE": "SkyEurope",
835 | "SO": "Sunshine Airlines",
836 | "JK": "Spanair",
837 | "1Z": "Sabre Pacific",
838 | "1S": "Sabre",
839 | "1H": "Siren-Travel",
840 | "1Q": "Sirena",
841 | "1K": "Sutra",
842 | "2C": "SNCF",
843 | "S0": "Slok Air Gambia",
844 | "S3": "Santa Barbara Airlines",
845 | "H2": "Sky Airline",
846 | "OO": "SkyWest Airlines",
847 | "BC": "Skymark Airlines",
848 | "LJ": "Sierra National Airlines",
849 | "MI": "SilkAir",
850 | "6Q": "Slovak Airlines",
851 | "PY": "Surinam Airways",
852 | "NB": "Sterling Airlines",
853 | "IE": "Solomon Airlines",
854 | "6W": "Saratov Airlines Joint Stock Company",
855 | "S5": "Trast Aero",
856 | "R1": "Sirin",
857 | "O3": "SF Airlines",
858 | "EQ": "TAME",
859 | "TP": "TAP Portugal",
860 | "TU": "Tunisair",
861 | "3V": "TNT Airways",
862 | "T2": "Thai Air Cargo",
863 | "TQ": "Tandem Aero",
864 | "ZT": "Titan Airways",
865 | "DG": "Tigerair Philippines",
866 | "TG": "Thai Airways International",
867 | "TK": "Turkish Airlines",
868 | "T7": "Twin Jet",
869 | "3P": "Tiara Air",
870 | "TI": "Tol-Air Services",
871 | "BY": "Thomson Airways",
872 | "PM": "Tropic Air",
873 | "QT": "TAMPA",
874 | "K3": "Taquan Air Services",
875 | "GE": "TransAsia Airways",
876 | "HV": "Transavia Holland",
877 | "VR": "TACV",
878 | "T9": "Thai Star Airlines",
879 | "9T": "Transwest Air",
880 | "UN": "Transaero Airlines",
881 | "T5": "Turkmenhovayollary",
882 | "T6": "Tavrey Airlines",
883 | "TW": "T'way Air",
884 | "6B": "TUIfly Nordic",
885 | "DT": "TAAG Angola Airlines",
886 | "SF": "Tassili Airlines",
887 | "TJ": "Tradewind Aviation",
888 | "1E": "Travelsky Technology",
889 | "2H": "Thalys",
890 | "1L": "Open Skies Consultative Commission",
891 | "RO": "Tarom",
892 | "3T": "Turan Air",
893 | "T4": "TRIP Linhas Aéreas",
894 | "L6": "Tbilaviamsheni",
895 | "XN": "XpressAir",
896 | "VO": "Tyrolean Airways",
897 | "U5": "USA3000 Airlines",
898 | "UA": "United Airlines",
899 | "4H": "United Airways",
900 | "U6": "Ural Airlines",
901 | "UF": "UM Airlines",
902 | "6Z": "Ukrainian Cargo Airways",
903 | "5X": "United Parcel Service",
904 | "US": "US Airways",
905 | "UH": "US Helicopter",
906 | "UT": "UTair Aviation",
907 | "HY": "Uzbekistan Airways",
908 | "PS": "Ukraine International Airlines",
909 | "VA": "Viasa",
910 | "VF": "Valuair",
911 | "0V": "Vietnam Air Services Company (VASCO)",
912 | "VN": "Vietnam Airlines",
913 | "NN": "VIM Airlines",
914 | "2R": "Via Rail Canada",
915 | "Y4": "Volaris",
916 | "VI": "Volga-Dnepr Airlines",
917 | "TV": "Virgin Express",
918 | "VS": "Virgin Atlantic Airways",
919 | "ZG": "Viva Macau",
920 | "XF": "Vladivostok Air",
921 | "VM": "Viaggio Air",
922 | "9V": "Vipair Airlines",
923 | "RG": "VRG Linhas Aéreas",
924 | "VP": "VASP",
925 | "VG": "VLM Airlines",
926 | "WT": "Wasaya Airways",
927 | "2W": "Welcome Air",
928 | "WZ": "West African Airlines",
929 | "YH": "West Caribbean Airways",
930 | "8O": "West Coast Air",
931 | "WS": "WestJet",
932 | "XP": "Xtra Airways",
933 | "WF": "Widerøe",
934 | "IV": "Wind Jet",
935 | "7W": "Windrose Air",
936 | "8Z": "Wizz Air Bulgaria",
937 | "W6": "Wizz Air",
938 | "WO": "World Airways",
939 | "1P": "Worldspan",
940 | "MF": "Xiamen Airlines",
941 | "SE": "XL Airways France",
942 | "YL": "Yamal Airlines",
943 | "Y8": "Yangtze River Express",
944 | "Y0": "Yellow Air Taxi/Friendship Airways",
945 | "IY": "Yemenia",
946 | "C4": "Zimex Aviation",
947 | "Q3": "Zambian Airways",
948 | "Z4": "Zoom Airlines"
949 | }
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/cities.csv:
--------------------------------------------------------------------------------
1 | city,latitude,longitude,population
2 | '兰州',103.73, 36.03,3.61
3 | '西宁',101.74, 36.56,2.2
4 | '成都',104.06, 30.67,14.05
5 | '石家庄',114.48, 38.03,10.16
6 | '拉萨',102.73, 25.04,0.56
7 | '贵阳',106.71, 26.57,4.32
8 | '武汉',114.31, 30.52,9.79
9 | '郑州',113.65, 34.76,8.63
10 | '济南',117, 36.65,6.81
11 | '南京',118.78, 32.04,8.0
12 | '合肥',117.27, 31.86,5.7
13 | '杭州',120.19, 30.26,8.7
14 | '南昌',115.89, 28.68,5.04
15 | '福州',119.3, 26.08,7.12
16 | '广州',113.23, 23.16,12.7
17 | '长沙',113, 28.21,7.04
18 | '海口',110.35, 20.02,2.05
19 | '沈阳',123.38, 41.8,8.11
20 | '长春',125.35, 43.88,7.68
21 | '哈尔滨',126.63, 45.75,10.63
22 | '太原',112.53, 37.87,4.2
23 | '西安',108.95, 34.27,8.47
24 | '北京',116.46, 39.92,19.61
25 | '上海',121.48, 31.22,23.02
26 | '重庆',106.54, 29.59,28.85
27 | '天津',117.2, 39.13,12.94
28 | '呼和浩特',111.65, 40.82,2.87
29 | '南宁',108.33, 22.84,6.66
30 | '银川',106.27, 38.47,1.99
31 | '乌鲁木齐',87.68, 43.77,3.11
32 | '昆明',102.83,24.88,6.43
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/rails.csv:
--------------------------------------------------------------------------------
1 | line,order,from_city,to_city,distance,cost,speed
2 | 京沪线,1,北京,天津,90,22.5,160
3 | 京沪线,2,天津,济南,200,50,160
4 | 京沪线,3,济南,徐州,390,97.5,160
5 | 京沪线,4,徐州,南京,421,105.25,160
6 | 京沪线,5,南京,上海,350,87.5,160
7 | 京哈线,1,北京,天津,92,23,250
8 | 京哈线,2,天津,秦皇岛,200,50,250
9 | 京哈线,3,秦皇岛,沈阳,337,84.25,250
10 | 京哈线,4,沈阳,长春,250,62.5,250
11 | 京哈线,5,长春,哈尔滨,380,95,250
12 | 京九线,1,北京,九江,1314,328.5,160
13 | 京九线,2,九江,南昌,135,33.75,160
14 | 京九线,3,南昌,深圳,923,230.75,160
15 | 京广线,1,北京,石家庄,300,75,160
16 | 京广线,2,石家庄,郑州,412,103,160
17 | 京广线,3,郑州,武汉,514,128.5,160
18 | 京广线,4,武汉,长沙,413,103.25,160
19 | 京广线,5,长沙,广州,707,176.75,160
20 | 成昆线,1,成都,昆明,1100,750,70
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/roads.csv:
--------------------------------------------------------------------------------
1 | road,order,from_city,to_city,distance,cost
2 | G2,1,北京,天津,81,35
3 | G2,2,天津,济南,323,120
4 | G2,3,济南,徐州,315,126
5 | G2,4,徐州,无锡,376,150
6 | G2,5,无锡,苏州,46,18
7 | G2,6,苏州,上海,79,32
8 | G1,1,北京,天津,98,39
9 | G1,2,天津,沈阳,563,225
10 | G1,3,沈阳,长春,406,162
11 | G1,4,长春,哈尔滨,184,74
12 | G3,1,北京,天津,79,29
13 | G3,2,天津,济南,330,129
14 | G3,3,济南,徐州,311,125
15 | G3,4,徐州,合肥,326,110
16 | G3,5,合肥,福州,549,220
17 | G4,1,北京,石家庄,273,109
18 | G4,2,石家庄,郑州,455,182
19 | G4,3,郑州,武汉,410,164
20 | G4,4,武汉,长沙,352,141
21 | G4,5,长沙,广州,619,248
22 | G4,6,广州,深圳,170,68
23 | G5,1,北京,石家庄,267,105
24 | G5,2,石家庄,太原,238,95
25 | G5,3,太原,西安,530,212
26 | G5,4,西安,成都,747,299
27 | G5,5,成都,昆明,934,374
28 | G40,1,上海,南京,301,150
29 | G40,2,南京,合肥,123,49
30 | G40,3,合肥,西安,919,368
31 | G6,3,呼和浩特,银川,718,220
32 | G6,4,银川,兰州,440,130
33 | G6,5,兰州,西宁,225,75
34 | G6,6,西宁,拉萨,1917,510
35 | G30,10,兰州,乌鲁木齐,1905,500
36 | G60,1,上海,杭州,176,50
37 | G75,10,重庆,贵阳,400,125
38 | G75,11,贵阳,南宁,587,170
39 | G75,12,南宁,海口,482,145
40 |
41 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/social-nodes.csv:
--------------------------------------------------------------------------------
1 | id
2 | "Alice"
3 | "Bridget"
4 | "Charles"
5 | "Doug"
6 | "Mark"
7 | "Michael"
8 | "David"
9 | "Amy"
10 | "James"
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/social-relationships.csv:
--------------------------------------------------------------------------------
1 | src,dst,relationship
2 | "Alice","Bridget","FOLLOWS"
3 | "Alice","Charles","FOLLOWS"
4 | "Mark","Doug","FOLLOWS"
5 | "Bridget","Michael","FOLLOWS"
6 | "Doug","Mark","FOLLOWS"
7 | "Michael","Alice","FOLLOWS"
8 | "Alice","Michael","FOLLOWS"
9 | "Bridget","Alice","FOLLOWS"
10 | "Michael","Bridget","FOLLOWS"
11 | "Charles","Doug","FOLLOWS"
12 | "Bridget","Doug","FOLLOWS"
13 | "Michael","Doug","FOLLOWS"
14 | "Alice","Doug","FOLLOWS"
15 | "Mark","Alice","FOLLOWS"
16 | "David","Amy","FOLLOWS"
17 | "James","David","FOLLOWS"
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/sw-nodes.csv:
--------------------------------------------------------------------------------
1 | id
2 | "six"
3 | "pandas"
4 | "numpy"
5 | "python-dateutil"
6 | "pytz"
7 | "pyspark"
8 | "matplotlib"
9 | "spacy"
10 | "py4j"
11 | "jupyter"
12 | "jpy-console"
13 | "nbconvert"
14 | "ipykernel"
15 | "jpy-client"
16 | "jpy-core"
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/sw-relationships.csv:
--------------------------------------------------------------------------------
1 | src,dst,relationship
2 | "pandas","numpy","DEPENDS_ON"
3 | "pandas","pytz","DEPENDS_ON"
4 | "pandas","python-dateutil","DEPENDS_ON"
5 | "python-dateutil","six","DEPENDS_ON"
6 | "pyspark","py4j","DEPENDS_ON"
7 | "matplotlib","numpy","DEPENDS_ON"
8 | "matplotlib","python-dateutil","DEPENDS_ON"
9 | "matplotlib","six","DEPENDS_ON"
10 | "matplotlib","pytz","DEPENDS_ON"
11 | "spacy","six","DEPENDS_ON"
12 | "spacy","numpy","DEPENDS_ON"
13 | "jupyter","nbconvert","DEPENDS_ON"
14 | "jupyter","ipykernel","DEPENDS_ON"
15 | "jupyter","jpy-console","DEPENDS_ON"
16 | "jpy-console","jpy-client","DEPENDS_ON"
17 | "jpy-console","ipykernel","DEPENDS_ON"
18 | "jpy-client","jpy-core","DEPENDS_ON"
19 | "nbconvert","jpy-core","DEPENDS_ON"
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/transport-nodes.csv:
--------------------------------------------------------------------------------
1 | id,latitude,longitude,population
2 | "Amsterdam",52.379189,4.899431,821752
3 | "Utrecht",52.092876,5.104480,334176
4 | "Den Haag",52.078663,4.288788,514861
5 | "Immingham",53.61239,-0.22219,9642
6 | "Doncaster",53.52285,-1.13116,302400
7 | "Hoek van Holland",51.9775,4.13333,9382
8 | "Felixstowe",51.96375,1.3511,23689
9 | "Ipswich",52.05917,1.15545,133384
10 | "Colchester",51.88921,0.90421,104390
11 | "London",51.509865,-0.118092,8787892
12 | "Rotterdam",51.9225,4.47917,623652
13 | "Gouda",52.01667,4.70833,70939
14 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/data/transport-relationships.csv:
--------------------------------------------------------------------------------
1 | src,dst,relationship,cost
2 | "Amsterdam","Utrecht","EROAD",46
3 | "Amsterdam","Den Haag","EROAD",59
4 | "Den Haag","Rotterdam","EROAD",26
5 | "Amsterdam","Immingham","EROAD",369
6 | "Immingham","Doncaster","EROAD",74
7 | "Doncaster","London","EROAD",277
8 | "Hoek van Holland","Den Haag","EROAD",27
9 | "Felixstowe","Hoek van Holland","EROAD",207
10 | "Ipswich","Felixstowe","EROAD",22
11 | "Colchester","Ipswich","EROAD",32
12 | "London","Colchester","EROAD",106
13 | "Gouda","Rotterdam","EROAD",25
14 | "Gouda","Utrecht","EROAD",35
15 | "Den Haag","Gouda","EROAD",32
16 | "Hoek van Holland","Rotterdam","EROAD",33
17 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/iptable.txt:
--------------------------------------------------------------------------------
1 | # IP地址
2 | 1 139.9.195.167
3 | 2 139.159.232.23
4 | 3 139.9.190.234
5 | 4 139.9.86.224
6 | 5 139.159.232.41
7 | 6 139.9.36.181
8 | 7 139.159.192.180
9 | 8 139.159.200.12
10 | 9 139.159.187.241
11 | 10 139.9.202.39
12 | 11 139.9.44.8
13 | 12 139.9.223.15
14 | 13 139.9.42.177
15 | 14 139.9.206.233
16 | 15 139.9.3.14
17 | 16 139.9.58.241
18 | 17 139.9.177.84
19 | 18 139.159.227.231
20 | 19 139.159.232.64
21 | 20 139.9.72.128
22 | 21 106.14.147.56
23 | 22 106.14.143.118
24 | 23 47.103.125.189
25 | 24 47.103.125.178
26 | 25 106.15.234.171
27 | 26 47.103.137.219
28 | 27 47.103.71.146
29 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/kaoshi.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/graphway/neo4j-algo/866ef1a54428484c78731956033c001aaadcae84/培训/图数据库及图算法/kaoshi.docx
--------------------------------------------------------------------------------
/培训/图数据库及图算法/procedures/README.md:
--------------------------------------------------------------------------------
1 | # 数据库扩展的Java样例工程
2 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/procedures/dependency-reduced-pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | com.mygroup
5 | procedures
6 | 1.0-SNAPSHOT
7 |
8 |
9 |
10 | maven-compiler-plugin
11 | 3.8.0
12 |
13 | 8
14 | 8
15 |
16 |
17 |
18 | maven-shade-plugin
19 | 3.2.1
20 |
21 |
22 | package
23 |
24 | shade
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | org.neo4j
34 | neo4j
35 | 3.5.5
36 | provided
37 |
38 |
39 | neo4j-kernel
40 | org.neo4j
41 |
42 |
43 | neo4j-lucene-index
44 | org.neo4j
45 |
46 |
47 | neo4j-fulltext-index
48 | org.neo4j
49 |
50 |
51 | neo4j-graph-algo
52 | org.neo4j
53 |
54 |
55 | neo4j-udc
56 | org.neo4j
57 |
58 |
59 | neo4j-data-collector
60 | org.neo4j
61 |
62 |
63 | neo4j-cypher
64 | org.neo4j
65 |
66 |
67 | neo4j-jmx
68 | org.neo4j
69 |
70 |
71 | neo4j-bolt
72 | org.neo4j
73 |
74 |
75 | neo4j-consistency-check
76 | org.neo4j
77 |
78 |
79 |
80 |
81 | org.neo4j.test
82 | neo4j-harness
83 | 3.5.5
84 | test
85 |
86 |
87 | neo4j-server
88 | org.neo4j.app
89 |
90 |
91 | neo4j-common
92 | org.neo4j
93 |
94 |
95 | neo4j-kernel
96 | org.neo4j
97 |
98 |
99 | neo4j-io
100 | org.neo4j
101 |
102 |
103 | jersey-client
104 | com.sun.jersey
105 |
106 |
107 | neo4j-server
108 | org.neo4j.app
109 |
110 |
111 | commons-codec
112 | commons-codec
113 |
114 |
115 | httpclient
116 | org.apache.httpcomponents
117 |
118 |
119 | httpcore
120 | org.apache.httpcomponents
121 |
122 |
123 |
124 |
125 | org.neo4j.driver
126 | neo4j-java-driver
127 | 1.7.2
128 | test
129 |
130 |
131 | junit
132 | junit
133 | 4.12
134 | test
135 |
136 |
137 | hamcrest-core
138 | org.hamcrest
139 |
140 |
141 |
142 |
143 |
144 | 0.7.30
145 | 3.5.5
146 | UTF-8
147 | 1.7.2
148 |
149 |
150 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/procedures/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.mygroup
8 | procedures
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 3.5.5
13 | 1.7.2
14 | 0.7.30
15 | UTF-8
16 |
17 |
18 |
19 |
20 | org.neo4j
21 | neo4j
22 | ${neo4j.version}
23 | provided
24 |
25 |
26 |
27 | org.neo4j.test
28 | neo4j-harness
29 | ${neo4j.version}
30 | test
31 |
32 |
33 |
34 | org.neo4j.driver
35 | neo4j-java-driver
36 | ${neo4j.driver.version}
37 | test
38 |
39 |
40 |
41 | junit
42 | junit
43 | 4.12
44 | test
45 |
46 |
47 |
48 | org.roaringbitmap
49 | RoaringBitmap
50 | ${roaring.version}
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.apache.maven.plugins
58 | maven-compiler-plugin
59 | 3.8.0
60 |
61 | 8
62 | 8
63 |
64 |
65 |
66 | maven-shade-plugin
67 | 3.2.1
68 |
69 |
70 | package
71 |
72 | shade
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/procedures/procedures.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
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 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/procedures/src/main/java/com/mypackage/Procedures.java:
--------------------------------------------------------------------------------
1 | package com.mypackage;
2 |
3 | import com.mypackage.results.*;
4 |
5 | import org.neo4j.graphdb.*;
6 | import org.neo4j.logging.Log;
7 | import org.neo4j.procedure.*;
8 | import org.roaringbitmap.RoaringBitmap;
9 |
10 | import java.io.IOException;
11 | import java.util.HashSet;
12 | import java.util.Iterator;
13 | import java.util.stream.Stream;
14 |
15 |
16 | public class Procedures {
17 |
18 | // 下面的行声明需要包括GraphDatabaseService类
19 | // 作为项目运行的环境(context)。
20 | @Context
21 | public GraphDatabaseService db;
22 |
23 | // 获得日志操作类的实例。
24 | // 标准日志通常是`data/log/neo4j.log`。
25 | @Context
26 | public Log log;
27 |
28 | @Procedure(name = "com.mypackage.hello", mode = Mode.READ)
29 | @Description("CALL com.mypackage.hello(String name)")
30 | public Stream hello(@Name("name") String name) {
31 | return Stream.of(new StringResult("Hello, " + name + "!"));
32 | }
33 |
34 | @UserFunction(name = "com.mypackage.greetings")
35 | @Description("com.mypackage.greetings(String name)")
36 | public String greetings(@Name("name") String name) {
37 | return new String("Hello, " + name + "!");
38 | }
39 |
40 | @UserAggregationFunction
41 | @Description( "com.mypackage.eldestAge(age) – 返回最大的年龄。" )
42 | public LongIntegerAggregator eldestAge ()
43 | {
44 | return new LongIntegerAggregator();
45 | }
46 |
47 | public static class LongIntegerAggregator
48 | {
49 | private Long eldest = 0l;
50 |
51 | @UserAggregationUpdate
52 | public void findEldest(
53 | @Name( "age" ) Long age )
54 | {
55 | if ( age > eldest)
56 | {
57 | eldest = age;
58 | }
59 | }
60 |
61 | @UserAggregationResult
62 | public Long result()
63 | {
64 | return eldest;
65 | }
66 | }
67 |
68 | // 统计k-度邻居的数量knn1:使用HashSet保存节点,方向无关
69 | // 参数:node - 起始节点, distance - 距离
70 | @Procedure(name = "com.mypackage.knn1.count", mode = Mode.READ)
71 | @Description("CALL com.mypackage.knn1.count(Node node, Long distnace)")
72 | public Stream neighbourCount1(@Name("node") Node node,
73 | @Name(value="distance", defaultValue = "1") Long distance)
74 | throws IOException
75 | {
76 | if (distance < 1) return Stream.empty();
77 |
78 | if (node == null) return Stream.empty();
79 |
80 | Iterator iterator;
81 | Node current;
82 |
83 | HashSet seen = new HashSet<>(); // 保存找到的节点
84 | HashSet nextA = new HashSet<>(); // 保存偶数层节点
85 | HashSet nextB = new HashSet<>(); // 保存奇数层节点
86 |
87 | // 处理起始节点
88 | seen.add(node);
89 | nextA.add(node);
90 |
91 | // 寻找第一层的节点 => nextB
92 | for (Relationship r : node.getRelationships()) {
93 | nextB.add(r.getOtherNode(node));
94 | }
95 |
96 | // 从第一层的节点开始,寻找下一层节点、直到到达distance层
97 | for (int i = 1; i < distance; i++) {
98 | // 这里处理偶数层:2、4、6、8...
99 |
100 | // 去除已经访问过的节点
101 | nextB.removeAll(seen);
102 |
103 | seen.addAll(nextB);
104 | nextA.clear();
105 | iterator = nextB.iterator();
106 |
107 | while (iterator.hasNext()) {
108 | current = iterator.next();
109 | for (Relationship r : current.getRelationships()) {
110 | nextA.add(r.getOtherNode(current));
111 | }
112 | }
113 |
114 | i++;
115 |
116 | if (i < distance) {
117 | // 这里处理奇数层:3、5、7...
118 | nextA.removeAll(seen);
119 | seen.addAll(nextA);
120 | nextB.clear();
121 | iterator = nextA.iterator();
122 | while (iterator.hasNext()) {
123 | current = iterator.next();
124 | for (Relationship r : current.getRelationships()) {
125 | nextB.add(r.getOtherNode(current));
126 | }
127 | }
128 | }
129 | }
130 |
131 | // 退出循环时,将最后一层的节点保存到已访问节点列表中
132 | if ((distance % 2) == 0) {
133 | nextA.removeAll(seen);
134 | seen.addAll(nextA);
135 | } else {
136 | nextB.removeAll(seen);
137 | seen.addAll(nextB);
138 | }
139 |
140 | // 去除起始节点
141 | seen.remove(node);
142 | return Stream.of(new LongResult((long) seen.size()));
143 | }
144 |
145 | // 统计k-度邻居的数量knn1:使用RoaringBitmap保存节点,方向无关
146 | // 参数:node - 起始节点, distance - 距离
147 | @Procedure(name = "com.mypackage.knn2.count", mode = Mode.READ)
148 | @Description("CALL com.mypackage.knn2.count(Node node, Long distnace)")
149 | public Stream neighbourCount2(@Name("node") Node node,
150 | @Name(value="distance", defaultValue = "1") Long distance)
151 | throws IOException
152 | {
153 | if (distance < 1) return Stream.empty();
154 |
155 | if (node == null) return Stream.empty();
156 |
157 | Iterator iterator;
158 | Node current;
159 |
160 | RoaringBitmap seen = new RoaringBitmap(); // 保存找到的节点
161 | RoaringBitmap nextA = new RoaringBitmap(); // 保存偶数层节点
162 | RoaringBitmap nextB = new RoaringBitmap(); // 保存奇数层节点
163 |
164 | int startNodeId = (int) node.getId();
165 |
166 | // 处理起始节点
167 | seen.add(startNodeId);
168 | nextA.add(startNodeId);
169 |
170 | // 寻找第一层的节点 => nextB
171 | for (Relationship r : node.getRelationships()) {
172 | nextB.add((int) r.getEndNodeId());
173 | nextB.add((int) r.getStartNodeId());
174 | }
175 |
176 | // 从第一层的节点开始,寻找下一层节点、直到到达distance层
177 | for (int i = 1; i < distance; i++) {
178 | // 这里处理偶数层:2、4、6、8...
179 |
180 | // 去除已经访问过的节点
181 | nextB.andNot(seen);
182 | seen.or(nextB);
183 | nextA.clear();
184 |
185 | for (Integer nodeId : nextB) {
186 | for (Relationship r : db.getNodeById((long) nodeId).getRelationships()) {
187 | nextA.add((int) r.getEndNodeId());
188 | nextA.add((int) r.getStartNodeId());
189 | }
190 | }
191 |
192 | i++;
193 |
194 | if (i < distance) {
195 | // 这里处理奇数层:3、5、7...
196 | nextA.andNot(seen);
197 | seen.or(nextA);
198 | nextB.clear();
199 |
200 | for (Integer nodeId : nextA) {
201 | for (Relationship r : db.getNodeById((long) nodeId).getRelationships()) {
202 | nextB.add((int) r.getEndNodeId());
203 | nextB.add((int) r.getStartNodeId());
204 | }
205 | }
206 | }
207 | }
208 |
209 | // 退出循环时,将最后一层的节点保存到已访问节点列表中
210 | if ((distance % 2) == 0) {
211 | nextA.andNot(seen);
212 | seen.or(nextA);
213 | } else {
214 | nextB.andNot(seen);
215 | seen.or(nextB);
216 | }
217 |
218 | // 去除起始节点
219 | seen.remove(startNodeId);
220 |
221 | return Stream.of(new LongResult((long) seen.getCardinality()));
222 | }
223 | } // class
224 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/procedures/src/main/java/com/mypackage/results/LongResult.java:
--------------------------------------------------------------------------------
1 | package com.mypackage.results;
2 |
3 | public class LongResult {
4 | public static final LongResult NULL = new LongResult(null);
5 | public final Long value;
6 |
7 | public LongResult(Long value) {
8 | this.value = value;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/procedures/src/main/java/com/mypackage/results/StringResult.java:
--------------------------------------------------------------------------------
1 | package com.mypackage.results;
2 |
3 | public class StringResult {
4 | public final static StringResult EMPTY = new StringResult(null);
5 | public final String value;
6 |
7 | public StringResult(String value) {
8 | this.value = value;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/spark/README.md:
--------------------------------------------------------------------------------
1 | # 培训课程中使用的Spark程序
2 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/spark/交通图:
--------------------------------------------------------------------------------
1 | # // tag::imports[]
2 | from pyspark.sql.types import *
3 | from graphframes import *
4 | # // end::imports[]
5 | from pyspark.conf import SparkConf
6 | from pyspark.sql import SparkSession
7 |
8 | SparkSession.builder.config(conf=SparkConf())
9 |
10 | spark = SparkSession.builder \
11 | .master("local") \
12 | .appName("transport") \
13 | .config("", "") \
14 | .getOrCreate()
15 |
16 | # // tag::load-graph-frame[]
17 | def create_transport_graph():
18 | node_fields = [
19 | StructField("id", StringType(), True),
20 | StructField("latitude", FloatType(), True),
21 | StructField("longitude", FloatType(), True),
22 | StructField("population", IntegerType(), True)
23 | ]
24 | nodes = spark.read.csv("data/transport-nodes.csv", header=True,
25 | schema=StructType(node_fields))
26 |
27 | rels = spark.read.csv("data/transport-relationships.csv", header=True)
28 | reversed_rels = rels.withColumn("newSrc", rels.dst) \
29 | .withColumn("newDst", rels.src) \
30 | .drop("dst", "src") \
31 | .withColumnRenamed("newSrc", "src") \
32 | .withColumnRenamed("newDst", "dst") \
33 | .select("src", "dst", "relationship", "cost")
34 |
35 | relationships = rels.union(reversed_rels)
36 |
37 | return GraphFrame(nodes, relationships)
38 | # // end::load-graph-frame[]
39 |
40 | g = create_transport_graph()
41 |
--------------------------------------------------------------------------------
/培训/图数据库及图算法/spark/图算法一__寻路问题与图算法.txt.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/graphway/neo4j-algo/866ef1a54428484c78731956033c001aaadcae84/培训/图数据库及图算法/spark/图算法一__寻路问题与图算法.txt.txt
--------------------------------------------------------------------------------
/培训/图数据库及图算法/spark/图算法三__社区发现算法.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/graphway/neo4j-algo/866ef1a54428484c78731956033c001aaadcae84/培训/图数据库及图算法/spark/图算法三__社区发现算法.txt
--------------------------------------------------------------------------------
/培训/图数据库及图算法/spark/图算法二__中心性算法.txt.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/graphway/neo4j-algo/866ef1a54428484c78731956033c001aaadcae84/培训/图数据库及图算法/spark/图算法二__中心性算法.txt.txt
--------------------------------------------------------------------------------
/培训/图数据库及图算法/考试.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | 考试地址
4 | https://www.kaoshixing.com/exam/exam_skip_login/320078/150144
5 |
6 |
7 | 考试地址2
8 | https://exam.kaoshixing.com/exam/exam_skip_login/320148/150144
9 |
10 |
11 | 登录方式:姓名,电子邮件
12 |
--------------------------------------------------------------------------------