├── 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 | --------------------------------------------------------------------------------