Cypher: Como a query language do Neo4j foiconstruída e como usá-la tldr: Cypher internals em 15 minutos
Quem é vc?
Quem é vc? Adriano Almeida  @adrianoalmeida7   ahalmeida.com
Quem é vc? Adriano Almeida  @adrianoalmeida7   ahalmeida.com
Quem é vc? Adriano Almeida  @adrianoalmeida7   ahalmeida.com
Quem é vc? Adriano Almeida  @adrianoalmeida7   ahalmeida.com
Buscando dados no Neo4j
Buscando dados no Neo4j      1. Traverse API Clássica
Buscando dados no Neo4j                        1. Traverse API Clássicaprivate static Traverser quemCodouOMatrix(final Nod...
Buscando dados no Neo4j      2. Traverse API Nova
Buscando dados no Neo4j                             2. Traverse API Novaprivate static Traverser quemCodouOMatrix( final N...
Buscando dados no Neo4j         3. Cypher
Buscando dados no Neo4j               3. Cypher   start programmer=(3)   match (programmer)-[:PAIRED]->(pair)   where pair...
Buscando dados no Neo4j                             3. Cypherprivate static Iterator<Node> comQuemUmDevPareou()	 {	 	 Exec...
Buscando dados no Neo4j             3. Cypher- Parsing- Execução
Definindo a linguagem    Start   Match       start programmer=(3)               match (programmer)-[:PAIRED]->(pair)  Where...
Por partes: Start Clausestart ::= "start" {"," nodeByIds | nodeByIndex | nodeByIndexQuery |relsByIds | relsByIndex }nodeBy...
Por partes: Start Clause Como implementar o parser disso?
Por partes: Start Clause    Scala + Parser Combinators
Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens {  def start...
Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens {  def start...
Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens {  def start...
Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens {  def start...
ASTQuery.scalapackage org.neo4j.cypher.commandscase class Start(startItems: StartItem*)StartItem.scalapackage org.neo4j.cy...
Por partes: Outras Clauses        (não dá tempo)        http://chu.pe/8K
Toda a querypackage org.neo4j.cypher.parserclass CypherParser extends JavaTokenParsers with StartClause with MatchClause w...
A execuçãoExecutionEngine.scala  http://chu.pe/8N
PipesStartPipe
PipesStartPipe -> MatchPipe
PipesStartPipe -> MatchPipe -> NamedPathPipe
PipesStartPipe -> MatchPipe -> NamedPathPipe ->FilterPipe
PipesStartPipe -> MatchPipe -> NamedPathPipe ->FilterPipe -> TransformPipe (Aggregation, Sort & Slice)
PipesStartPipe -> MatchPipe -> NamedPathPipe ->FilterPipe -> TransformPipe (Aggregation, Sort & Slice)-> ColumnFilterPipe
Prós e Contras+ Objetiva+ Ops Friendly+ Poderosa (algoritmos de grafos e pattern matching)- Verbosa- Performance (ainda)+/...
Explicação mais        detalhada• http://ahalmeida.com/
DisclaimerCódigos da versão 1.4.2
Obrigado@adrianoalmeida7
Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi construída e como usá-la
Upcoming SlideShare
Loading in …5
×

Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi construída e como usá-la

855 views

Published on

Published in: Self Improvement, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
855
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Cypher inside out: Como a linguagem de pesquisas em grafo do Neo4j foi construída e como usá-la

    1. 1. Cypher: Como a query language do Neo4j foiconstruída e como usá-la tldr: Cypher internals em 15 minutos
    2. 2. Quem é vc?
    3. 3. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
    4. 4. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
    5. 5. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
    6. 6. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
    7. 7. Buscando dados no Neo4j
    8. 8. Buscando dados no Neo4j 1. Traverse API Clássica
    9. 9. Buscando dados no Neo4j 1. Traverse API Clássicaprivate static Traverser quemCodouOMatrix(final Node startNode) { return startNode.traverse(Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, new ReturnableEvaluator() { @Override public boolean isReturnableNode(final TraversalPosition currentPos) { return !currentPos.isStartNode() && currentPos.lastRelationshipTraversed().isType(RelTypes.CODED_BY); } }, RelTypes.CODED_BY, Direction.OUTGOING, RelTypes.KNOWS, Direction.OUTGOING ); }
    10. 10. Buscando dados no Neo4j 2. Traverse API Nova
    11. 11. Buscando dados no Neo4j 2. Traverse API Novaprivate static Traverser quemCodouOMatrix( final Node startNode ) { TraversalDescription td = Traversal.description() .breadthFirst() .relationships( RelTypes.CODED_BY, Direction.OUTGOING ) .relationships( RelTypes.KNOWS, Direction.OUTGOING ) .evaluator( Evaluators.returnWhereLastRelationshipTypeIs( RelTypes.CODED_BY ) ); return td.traverse( startNode ); }
    12. 12. Buscando dados no Neo4j 3. Cypher
    13. 13. Buscando dados no Neo4j 3. Cypher start programmer=(3) match (programmer)-[:PAIRED]->(pair) where pair.age > 30 return pair order by pair.age skip 5 limit 10
    14. 14. Buscando dados no Neo4j 3. Cypherprivate static Iterator<Node> comQuemUmDevPareou() { ExecutionEngine engine = new ExecutionEngine(db); ExecutionResult result = engine.execute( "start programmer=(3) " + "match (programmer)-[:PAIRED]->(pair) where pair.age > 30 " + "return pair " + "order by pair.age " + "skip 5 limit 10" ); Iterator<Node> pairs = result.columnAs( "pair" ); return pairs; }
    15. 15. Buscando dados no Neo4j 3. Cypher- Parsing- Execução
    16. 16. Definindo a linguagem Start Match start programmer=(3) match (programmer)-[:PAIRED]->(pair) Where where pair.age > 30 Return return pair order by pair.age Order By skip 5 limit 10Skip & Limit
    17. 17. Por partes: Start Clausestart ::= "start" {"," nodeByIds | nodeByIndex | nodeByIndexQuery |relsByIds | relsByIndex }nodeByIds ::= identity "=" "(" {"," number} ")"nodeByIndex ::= identity "=" "(" identity "," identity "," string ")"nodeByIndexQuery ::= identity "=" "(" identity "," string ")"relsByIds ::= identity "=" "<" { "," number } ">"relsByIndex ::= identity "=" "<" identity "," identity "," string ">"
    18. 18. Por partes: Start Clause Como implementar o parser disso?
    19. 19. Por partes: Start Clause Scala + Parser Combinators
    20. 20. Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens { def start: Parser[Start] = ignoreCase("start") ~> rep1sep(nodeByIds | nodeByIndex | nodeByIndexQuery | relsByIds | relsByIndex, ",") ^^ (Start(_: _*)) def nodeByIds = identity ~ "=" ~ "(" ~ rep1sep(wholeNumber, ",") ~ ")" ^^ { case varName ~ "=" ~ "(" ~ id ~ ")" => NodeById(varName, id.map(_.toLong).toSeq: _*) } def nodeByIndex = identity ~ "=" ~ "(" ~ identity ~ "," ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ key ~ "," ~ value ~ ")" => NodeByIndex(varName, index, key, value) } def nodeByIndexQuery = identity ~ "=" ~ "(" ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ query ~ ")" => NodeByIndexQuery(varName, index, query) } def relsByIds = identity ~ "=" ~ "<" ~ rep1sep(wholeNumber, ",") ~ ">" ^^ { case varName ~ "=" ~ "<" ~ id ~ ">" => RelationshipById(varName, id.map(_.toLong).toSeq: _*) } def relsByIndex = identity ~ "=" ~ "<" ~ identity ~ "," ~ identity ~ "," ~ string ~ ">" ^^ { case varName ~ "=" ~ "<" ~ index ~ "," ~ key ~ "," ~ value ~ ">" => RelationshipByIndex(varName, index, key,value) }}
    21. 21. Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens { def start: Parser[Start] = ignoreCase("start") ~> rep1sep(nodeByIds | nodeByIndex | nodeByIndexQuery | relsByIds | relsByIndex, ",") ^^ (Start(_: _*)) def nodeByIds = identity ~ "=" ~ "(" ~ rep1sep(wholeNumber, ",") ~ ")" ^^ { case varName ~ "=" ~ "(" ~ id ~ ")" => NodeById(varName, id.map(_.toLong).toSeq: _*) } def nodeByIndex = identity ~ "=" ~ "(" ~ identity ~ "," ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ key ~ "," ~ value ~ ")" => NodeByIndex(varName, index, key, value) } def nodeByIndexQuery = identity ~ "=" ~ "(" ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ query ~ ")" => NodeByIndexQuery(varName, index, query) } def relsByIds = identity ~ "=" ~ "<" ~ rep1sep(wholeNumber, ",") ~ ">" ^^ { case varName ~ "=" ~ "<" ~ id ~ ">" => RelationshipById(varName, id.map(_.toLong).toSeq: _*) } def relsByIndex = identity ~ "=" ~ "<" ~ identity ~ "," ~ identity ~ "," ~ string ~ ">" ^^ { case varName ~ "=" ~ "<" ~ index ~ "," ~ key ~ "," ~ value ~ ">" => RelationshipByIndex(varName, index, key,value) }}
    22. 22. Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens { def start: Parser[Start] = ignoreCase("start") ~> rep1sep(nodeByIds | nodeByIndex | nodeByIndexQuery | relsByIds | relsByIndex, ",") ^^ (Start(_: _*)) def nodeByIds = identity ~ "=" ~ "(" ~ rep1sep(wholeNumber, ",") ~ ")" ^^ { case varName ~ "=" ~ "(" ~ id ~ ")" => NodeById(varName, id.map(_.toLong).toSeq: _*) } def nodeByIndex = identity ~ "=" ~ "(" ~ identity ~ "," ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ key ~ "," ~ value ~ ")" => NodeByIndex(varName, index, key, value) } def nodeByIndexQuery = identity ~ "=" ~ "(" ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ query ~ ")" => NodeByIndexQuery(varName, index, query) } def relsByIds = identity ~ "=" ~ "<" ~ rep1sep(wholeNumber, ",") ~ ">" ^^ { case varName ~ "=" ~ "<" ~ id ~ ">" => RelationshipById(varName, id.map(_.toLong).toSeq: _*) } def relsByIndex = identity ~ "=" ~ "<" ~ identity ~ "," ~ identity ~ "," ~ string ~ ">" ^^ { case varName ~ "=" ~ "<" ~ index ~ "," ~ key ~ "," ~ value ~ ">" => RelationshipByIndex(varName, index, key,value) }}
    23. 23. Por partes: Start Clausepackage org.neo4j.cypher.parsertrait StartClause extends JavaTokenParsers with Tokens { def start: Parser[Start] = ignoreCase("start") ~> rep1sep(nodeByIds | nodeByIndex | nodeByIndexQuery | relsByIds | relsByIndex, ",") ^^ (Start(_: _*)) def nodeByIds = identity ~ "=" ~ "(" ~ rep1sep(wholeNumber, ",") ~ ")" ^^ { case varName ~ "=" ~ "(" ~ id ~ ")" => NodeById(varName, id.map(_.toLong).toSeq: _*) } def nodeByIndex = identity ~ "=" ~ "(" ~ identity ~ "," ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ key ~ "," ~ value ~ ")" => NodeByIndex(varName, index, key, value) } def nodeByIndexQuery = identity ~ "=" ~ "(" ~ identity ~ "," ~ string ~ ")" ^^ { case varName ~ "=" ~ "(" ~ index ~ "," ~ query ~ ")" => NodeByIndexQuery(varName, index, query) } def relsByIds = identity ~ "=" ~ "<" ~ rep1sep(wholeNumber, ",") ~ ">" ^^ { case varName ~ "=" ~ "<" ~ id ~ ">" => RelationshipById(varName, id.map(_.toLong).toSeq: _*) } def relsByIndex = identity ~ "=" ~ "<" ~ identity ~ "," ~ identity ~ "," ~ string ~ ">" ^^ { case varName ~ "=" ~ "<" ~ index ~ "," ~ key ~ "," ~ value ~ ">" => RelationshipByIndex(varName, index, key,value) }}
    24. 24. ASTQuery.scalapackage org.neo4j.cypher.commandscase class Start(startItems: StartItem*)StartItem.scalapackage org.neo4j.cypher.commandsabstract sealed class StartItem(val variable:String)abstract class NodeStartItem(varName:String) extends StartItem(varName)case class NodeById(varName:String, id: Long*) extends NodeStartItem(varName)
    25. 25. Por partes: Outras Clauses (não dá tempo) http://chu.pe/8K
    26. 26. Toda a querypackage org.neo4j.cypher.parserclass CypherParser extends JavaTokenParsers with StartClause with MatchClause with WhereClause with ReturnClause with SkipLimitClause with OrderByClause with StringExtras { def query: Parser[Query] = start ~ opt(matching) ~ opt(where) ~ returns ~ opt(order) ~ opt(skip) ~ opt(limit) ^^ { case start ~ matching ~ where ~ returns ~ order ~ skip ~ limit => { val slice = (skip,limit) match { case (None,None) => None case (s,l) => Some(Slice(s,l)) } val (pattern:Option[Match], namedPaths:Option[NamedPaths]) = matching match { case Some((p,NamedPaths())) => (Some(p),None) case Some((Match(),nP)) => (None,Some(nP)) case Some((p,nP)) => (Some(p),Some(nP)) case None => (None,None) } Query(returns._1, start, pattern, where, returns._2, order, slice, namedPaths) } }
    27. 27. A execuçãoExecutionEngine.scala http://chu.pe/8N
    28. 28. PipesStartPipe
    29. 29. PipesStartPipe -> MatchPipe
    30. 30. PipesStartPipe -> MatchPipe -> NamedPathPipe
    31. 31. PipesStartPipe -> MatchPipe -> NamedPathPipe ->FilterPipe
    32. 32. PipesStartPipe -> MatchPipe -> NamedPathPipe ->FilterPipe -> TransformPipe (Aggregation, Sort & Slice)
    33. 33. PipesStartPipe -> MatchPipe -> NamedPathPipe ->FilterPipe -> TransformPipe (Aggregation, Sort & Slice)-> ColumnFilterPipe
    34. 34. Prós e Contras+ Objetiva+ Ops Friendly+ Poderosa (algoritmos de grafos e pattern matching)- Verbosa- Performance (ainda)+/- Work In Progress
    35. 35. Explicação mais detalhada• http://ahalmeida.com/
    36. 36. DisclaimerCódigos da versão 1.4.2
    37. 37. Obrigado@adrianoalmeida7

    ×