League of Graphs \w Neo4j

League of Graphs \w Neo4j

In this show-and-tell session we’ll find out how Neo4j can make us a professional League of Legends player. First, we’ll import game data into a Neo4j graph. Then we will push the limits of Cypher to uncover hidden secrets that lie in the depth of LoL.
• Which champions perform best as allies?
• What is the most effective strategy to advance your champion?
• What enemy team setup is the most dangerous?
This session covers a rarely seen graph domain (gaming) and will provide you will solid, factual advice on how to play LoL.

https://github.com/FylmTM/league-of-legends-research

Cf0dfe4a39a8b46ad220d11ff73b9e6c?s=128

Dmitrijs Vrublevskis

May 26, 2016
Tweet

Transcript

  1. Name Surname email@domain.com Presentation Title League of Graphs

  2. Dmitry Vrublevsky @Me Software engineer @ ƀ dmitry@vrublevsky.me @FylmTM į

    vrublevsky.me
  3. None
  4. None
  5. Neueda4j / awesome-neo4j {75 ̣} A curated list of Neo4j

    resources. Neueda4j / jetbrains-plugin-cypher {24 ̣} Cypher plugin for Jetbrains IDE’s. ? / ? {? ̣} Next awesome project!
  6. Agenda 1. League of Legends 2. Neo4j 3. Data import

    4. Queries
  7. None
  8. Winner? League of Legends “Poros are the mysterious, magical and

    most-loved inhabitants originating from the Howling Abyss.”
  9. League of Legends is multiplayer online battle arena, real-time strategy

    video game developed and published by Riot Games
  10. None
  11. Me Unranked Bronze Silver Gold Platinum Diamond Master Challenger

  12. None
  13. League of Legends? 1. I play this game a lot

    2. Rich API 3. There is library for API https://developer.riotgames.com
  14. None
  15. meraki-analytics/Orianna A Java adaptation of the Riot Games LoL API

    Summoner summoner = RiotAPI.getSummonerByName(“FylmTM"); 
 println(summoner.getName() + " is a level “ + summoner.getLevel());
  16. Neo4j Highly scalable native graph database that leverages data relationships

    as 
 first-class entities. by Neo Technology, Inc.
  17. http://db-engines.com/en/ranking

  18. GRAPH

  19. NOT GRAPH

  20. Features Native Processing & Storage ACID Cypher - Graph Query

    Language REST & Native API Lock Manager High-performance cache Clustering Backups Monitoring Community Enterprise
  21. First-class details: — :LIKES :DMITRY :JUG works_with: Neo4j day: 28.05.2016

    Properties Labels Type
  22. Native 1. “Native” storage 2. “Native” processing

  23. “Native” storage Specifically designed to store and manage graphs.

  24. http://neo4j.com/developer/graph-db-vs-rdbms/

  25. http://neo4j.com/developer/graph-db-vs-rdbms/

  26. http://neo4j.com/developer/graph-db-vs-rdbms/

  27. “Native” processing Efficient way of processing graph data since connected

    nodes physically “point” to each other a.k.a. “index-free adjacency”
  28. Storage layout Node (15 bytes) in_use next_rel_id next_prop_id labels extra

    Relationship (34 bytes) directed | in_use first_node second_node rel_type first_prev_rel_id first_next_rel_id second_prev_rel_id second_next_rel_id next_prop_id first_in_chain_markers
  29. Storage math Node_Offset = Node_Size * Node_ID Rel_Offset = Rel_Size

    * Rel_ID
  30. Traversal (Node -> Relationship) {5} Node (15 bytes) next_rel_id {2}

    {<int>} - entity id <int>B - offset Relationships (34 bytes) {0} 2 * 34 = 68 0B {1} 34B {2} 68B {3} 102B {4} 136B {5} 170B
  31. Traversal (Relationship -> Node) {2} Relationship (34 bytes) {<int>} -

    entity id <int>B - offset Nodes (15 bytes) {0} 0B {1} 15B {2} 30B {3} 45B {4} 60B {5} 75B first_node {1} second_node {4}
  32. “Native” summary O(1) traversal hops Avoid super nodes!

  33. Cypher Cypher is a declarative graph query language that allows

    for expressive and efficient querying. https://github.com/opencypher/openCypher
  34. Cypher ( ) - node --> - relationship Keywords: -

    MATCH - CREATE - WHERE - RETURN MATCH (jug) RETURN jug MATCH (attendees)-->(jug) 
 RETURN * MATCH (attendees)-->(jug) WHERE jug.city = “Kaunas”
 RETURN *
  35. Cypher MATCH (you:Person {name: "Dmitry"}) CREATE (you)-[like:LIKE]->(neo:Database {name: "Neo4j"}) RETURN

    you, like, neo
  36. Whiteboard friendly data modelling

  37. None
  38. None
  39. CREATE (alice:Person {name: "Alice"})
 CREATE (bob:Person {name: "Bob"})
 CREATE (carol:Person

    {name: "Carol"})
 CREATE (iphone:Device {name: "iPhone"})
 
 CREATE (alice)-[:HAS]->(iphone)
 CREATE (bob)-[:WANTS]->(iphone)
 
 CREATE (alice)<-[:FOLLOWS]-(bob)
 CREATE (alice)-[:FOLLOWS]->(bob)
 CREATE (carol)-[:FOLLOWS]->(bob)
 
 CREATE (bob)<-[:AUTHOR]-(:Comment {text: "Thoughts?"})
 <-[:COMMENT]-(iphone)
 CREATE (carol)<-[:AUTHOR]-(:Comment {text: "<3 it"})
 <-[:COMMENT]-(iphone)
  40. Data import 1. Retrieve data using Orianna 2. Load data

    as-is in Neo4j
  41. Dependencies dependencies {
 compile 'com.robrua:orianna:2.4.3-SNAPSHOT'
 compile 'org.neo4j:neo4j:2.3.3'
 }

  42. Create database File dbDir = new File(databasePath); 
 GraphDatabaseService db

    = new GraphDatabaseFactory()
 .newEmbeddedDatabaseBuilder(dbDir)
 .newGraphDatabase();
  43. Transaction try (Transaction tx = db.beginTx()) { 
 // Do

    cool stuff 
 tx.success();
 }
  44. Load data Summoner summoner = RiotAPI.getSummonerByName(“FylmTM"); Node node = db.createNode();


    node.addLabel(Labels.Summoner);
 node.setProperty(KEY_ID, summoner.getID());
 node.setProperty(KEY_NAME, summoner.getName());
 node.setProperty(KEY_LEVEL, summoner.getLevel());
  45. In the end

  46. None
  47. neo4j-contrib/neo4j-apoc-procedures Awesome procedures for Neo4j 3.0 - codenamed "apoc" //

    examines the full graph to create the meta-graph
 CALL apoc.meta.graph(); Apoc was the technician and driver on board of the Nebuchadnezzar in the Matrix movie. He was killed by Cypher.
  48. Import result • Season 6, EUNE region • Players: me

    & 7 friends MATCH (n) RETURN count(n) as nodeCount nodeCount 336729
  49. Queries

  50. Query #1 How many games I have played? MATCH (s:Summoner

    {name: "FylmTM"})
 MATCH (s)-[:PARTICIPATED|:PARTICIPATED_IN_MATCH]->(sMatch)
 RETURN count(sMatch); // 59 ms Count 110
  51. Query #2 Who are my friends? MATCH (s:Summoner {name: "FylmTM"})


    MATCH (s)-[:PARTICIPATED]-()-[:PARTICIPATED_IN_MATCH]
 ->(sMatch)<-
 [:PARTICIPATED_IN_MATCH]-()-[:PARTICIPATED]-(f)
 WITH f.name as friendName, count(f) as gamesTogether
 WHERE gamesTogether > 2
 RETURN friendName, gamesTogether
 ORDER BY gamesTogether DESC // 55 ms friendName gamesTogether Cryptael 107 Henua 28 Iger 11 XXpoMMou 10 yesCold 8 eskiuzi 3
  52. Query #3 Most dangerous champions? name total won lost %

    Alistar 7 1 6 86% Jax 12 3 9 75% LeBlanc 8 2 6 75% Dr. Mundo 7 2 5 71% Miss Fortune 10 3 7 70% MATCH (s:Summoner {name: "FylmTM"})
 MATCH (s)-[:PARTICIPATED]->()-[:PLAYED_FOR_TEAM]->
 (team {winner: true})<-[:HAS_TEAM]-()-[:HAS_TEAM]->(o)
 <-[:PLAYED_FOR_TEAM]-()-[:PARTICIPATED_WITH_CHAMPION]->(c)
 RETURN c.name as championName, count(c) as winCount
 ORDER BY winCount DESC
  53. Alistar Jax

  54. None
  55. Query #4 Any statistics? MATCH (s:Summoner) WHERE s.name IN ["MrMgr",

    "Cryptael"]
 MATCH (s)-[:PARTICIPATED|:PARTICIPANT_TIMELINE*2]->(pt)-[r]->(ptd)
 WHERE pt.role = "SOLO" AND pt.lane = "MIDDLE"
 AND r.name IN ["getCreepsPerMinDeltas", "getGoldPerMinDeltas"]
 WITH s.name as name, r.name as stat,
 sum(ptd.zero_to_ten) as `sum_0-10`,
 size(filter(x IN collect(ptd.zero_to_ten) WHERE x <> 0))
 as `size_0-10`,
 sum(ptd.ten_to_twenty) as `sum_10-20`,
 size(filter(x IN collect(ptd.ten_to_twenty) WHERE x <> 0))
 as `size_10-20`,
 sum(ptd.twenty_to_thirty) as `sum_20-30`,
 size(filter(x IN collect(ptd.twenty_to_thirty) WHERE x <> 0))
 as `size_20-30`,
 sum(ptd.thirty_to_end) as `sum_30+`,
 size(filter(x IN collect(ptd.thirty_to_end) WHERE x <> 0))
 as `size_30+`
 RETURN name, stat,
 `sum_0-10` / `size_0-10` as `0-10`,
 `sum_10-20` / `size_10-20` as `10-20`,
 `sum_20-30` / `size_20-30` as `20-30`,
 `sum_30+` / `size_30+` as `30+`
 ORDER BY name, stat
  56. creeps/min 0 2 4 6 8 0-10 10-20 20-30 30+

    Cryptael MrMgr gold/min 0 150 300 450 600 0-10 10-20 20-30 30+ Cryptael MrMgr Cryptael MrMgr (#27 in EUNE)
  57. Takeaways • Neo4j is easy to use • Build schema

    on the fly • Cypher is a handy tool for exploration • Find value in your data
  58. None