SlideShare a Scribd company logo
1 of 38
Cypher: Como a query
 language do Neo4j foi
construí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ássica
private 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
	 	 );	
}
Buscando dados no Neo4j
      2. Traverse API Nova
Buscando dados no Neo4j
                             2. Traverse API Nova


private 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 );
	 }
Buscando dados no Neo4j
         3. Cypher
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
Buscando dados no Neo4j
                             3. Cypher


private 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;
	 }
Buscando dados no Neo4j
             3. Cypher




- Parsing
- Execução
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 10

Skip & Limit
Por partes: Start Clause

start ::= "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 ">"
Por partes: Start Clause


 Como implementar o parser disso?
Por partes: Start Clause


    Scala + Parser Combinators
Por partes: Start Clause
package org.neo4j.cypher.parser

trait 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)
  }
}
Por partes: Start Clause
package org.neo4j.cypher.parser

trait 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)
  }
}
Por partes: Start Clause
package org.neo4j.cypher.parser

trait 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)
  }
}
Por partes: Start Clause
package org.neo4j.cypher.parser

trait 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)
  }
}
AST
Query.scala
package org.neo4j.cypher.commands

case class Start(startItems: StartItem*)




StartItem.scala
package org.neo4j.cypher.commands

abstract sealed class StartItem(val variable:String)

abstract class NodeStartItem(varName:String) extends StartItem(varName)

case class NodeById(varName:String, id: Long*) extends NodeStartItem(varName)
Por partes: Outras Clauses


        (não dá tempo)
        http://chu.pe/8K
Toda a query
package org.neo4j.cypher.parser


class 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)
      }
  }
A execução


ExecutionEngine.scala
  http://chu.pe/8N
Pipes



StartPipe
Pipes



StartPipe -> MatchPipe
Pipes



StartPipe -> MatchPipe -> NamedPathPipe
Pipes


StartPipe -> MatchPipe -> NamedPathPipe ->

FilterPipe
Pipes


StartPipe -> MatchPipe -> NamedPathPipe ->

FilterPipe -> TransformPipe (Aggregation, Sort & Slice)
Pipes

StartPipe -> 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)

+/- Work In Progress
Explicação mais
        detalhada

• http://ahalmeida.com/
Disclaimer

Códigos da versão 1.4.2
Obrigado

@adrianoalmeida7

More Related Content

What's hot

What's hot (20)

Short Introduction To "perl -d"
Short Introduction To "perl -d"Short Introduction To "perl -d"
Short Introduction To "perl -d"
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
Solr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg DonovanSolr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg Donovan
 
The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202The Ring programming language version 1.8 book - Part 96 of 202
The Ring programming language version 1.8 book - Part 96 of 202
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
Five
FiveFive
Five
 
What's new in Liferay Mobile SDK 2.0 for Android
What's new in Liferay Mobile SDK 2.0 for AndroidWhat's new in Liferay Mobile SDK 2.0 for Android
What's new in Liferay Mobile SDK 2.0 for Android
 
Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
Expression trees in c#
Expression trees in c#Expression trees in c#
Expression trees in c#
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
 
Living with garbage
Living with garbageLiving with garbage
Living with garbage
 
Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8Just-In-Time Compiler in PHP 8
Just-In-Time Compiler in PHP 8
 
The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194The Ring programming language version 1.5.3 book - Part 19 of 194
The Ring programming language version 1.5.3 book - Part 19 of 194
 
Redis Set Go
Redis Set GoRedis Set Go
Redis Set Go
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 

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

Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
ConFoo
 
To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2
Bahul Neel Upadhyaya
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 

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

Parboiled explained
Parboiled explainedParboiled explained
Parboiled explained
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
 
Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011Petitparser at the Deep into Smalltalk School 2011
Petitparser at the Deep into Smalltalk School 2011
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
Perl6 grammars
Perl6 grammarsPerl6 grammars
Perl6 grammars
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2
 
Tips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET ApplicationTips and Tricks of Developing .NET Application
Tips and Tricks of Developing .NET Application
 
Pattern Matching in Java 14
Pattern Matching in Java 14Pattern Matching in Java 14
Pattern Matching in Java 14
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Scala
ScalaScala
Scala
 
Algorithm and Programming (Introduction of dev pascal, data type, value, and ...
Algorithm and Programming (Introduction of dev pascal, data type, value, and ...Algorithm and Programming (Introduction of dev pascal, data type, value, and ...
Algorithm and Programming (Introduction of dev pascal, data type, value, and ...
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 

More from adrianoalmeida7 (6)

Onde e como investir na sua carreira
Onde e como investir na sua carreiraOnde e como investir na sua carreira
Onde e como investir na sua carreira
 
Neo4j e grafos com teoria e live coding
Neo4j e grafos com teoria e live codingNeo4j e grafos com teoria e live coding
Neo4j e grafos com teoria e live coding
 
Nosqlba
NosqlbaNosqlba
Nosqlba
 
Conexao java v-raptor
Conexao java v-raptorConexao java v-raptor
Conexao java v-raptor
 
QConSP: Do cache ao cluster, escalando com Rails
QConSP: Do cache ao cluster, escalando com RailsQConSP: Do cache ao cluster, escalando com Rails
QConSP: Do cache ao cluster, escalando com Rails
 
Oxente Rails 2010 - Persistindo em Graph databases
Oxente Rails 2010 - Persistindo em Graph databasesOxente Rails 2010 - Persistindo em Graph databases
Oxente Rails 2010 - Persistindo em Graph databases
 

Recently uploaded

KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...
KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...
KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...
Cara Menggugurkan Kandungan 087776558899
 
Girls in Mahipalpur (delhi) call me [🔝9953056974🔝] escort service 24X7
Girls in Mahipalpur  (delhi) call me [🔝9953056974🔝] escort service 24X7Girls in Mahipalpur  (delhi) call me [🔝9953056974🔝] escort service 24X7
Girls in Mahipalpur (delhi) call me [🔝9953056974🔝] escort service 24X7
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
February 2024 Recommendations for newsletter
February 2024 Recommendations for newsletterFebruary 2024 Recommendations for newsletter
February 2024 Recommendations for newsletter
ssuserdfec6a
 
the Husband rolesBrown Aesthetic Cute Group Project Presentation
the Husband rolesBrown Aesthetic Cute Group Project Presentationthe Husband rolesBrown Aesthetic Cute Group Project Presentation
the Husband rolesBrown Aesthetic Cute Group Project Presentation
brynpueblos04
 

Recently uploaded (15)

Dadar West Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
Dadar West Escorts 🥰 8617370543 Call Girls Offer VIP Hot GirlsDadar West Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
Dadar West Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
 
KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...
KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...
KLINIK BATA Jual obat penggugur kandungan 087776558899 ABORSI JANIN KEHAMILAN...
 
Goregaon West Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
Goregaon West Escorts 🥰 8617370543 Call Girls Offer VIP Hot GirlsGoregaon West Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
Goregaon West Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
 
Exploring Stoic Philosophy From Ancient Wisdom to Modern Relevance.pdf
Exploring Stoic Philosophy From Ancient Wisdom to Modern Relevance.pdfExploring Stoic Philosophy From Ancient Wisdom to Modern Relevance.pdf
Exploring Stoic Philosophy From Ancient Wisdom to Modern Relevance.pdf
 
Girls in Mahipalpur (delhi) call me [🔝9953056974🔝] escort service 24X7
Girls in Mahipalpur  (delhi) call me [🔝9953056974🔝] escort service 24X7Girls in Mahipalpur  (delhi) call me [🔝9953056974🔝] escort service 24X7
Girls in Mahipalpur (delhi) call me [🔝9953056974🔝] escort service 24X7
 
Pokemon Go... Unraveling the Conspiracy Theory
Pokemon Go... Unraveling the Conspiracy TheoryPokemon Go... Unraveling the Conspiracy Theory
Pokemon Go... Unraveling the Conspiracy Theory
 
February 2024 Recommendations for newsletter
February 2024 Recommendations for newsletterFebruary 2024 Recommendations for newsletter
February 2024 Recommendations for newsletter
 
Social Learning Theory presentation.pptx
Social Learning Theory presentation.pptxSocial Learning Theory presentation.pptx
Social Learning Theory presentation.pptx
 
Colaba Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
Colaba Escorts 🥰 8617370543 Call Girls Offer VIP Hot GirlsColaba Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
Colaba Escorts 🥰 8617370543 Call Girls Offer VIP Hot Girls
 
2023 - Between Philosophy and Practice: Introducing Yoga
2023 - Between Philosophy and Practice: Introducing Yoga2023 - Between Philosophy and Practice: Introducing Yoga
2023 - Between Philosophy and Practice: Introducing Yoga
 
the Husband rolesBrown Aesthetic Cute Group Project Presentation
the Husband rolesBrown Aesthetic Cute Group Project Presentationthe Husband rolesBrown Aesthetic Cute Group Project Presentation
the Husband rolesBrown Aesthetic Cute Group Project Presentation
 
Call Girls In Mumbai Just Genuine Call ☎ 7738596112✅ Call Girl Andheri East G...
Call Girls In Mumbai Just Genuine Call ☎ 7738596112✅ Call Girl Andheri East G...Call Girls In Mumbai Just Genuine Call ☎ 7738596112✅ Call Girl Andheri East G...
Call Girls In Mumbai Just Genuine Call ☎ 7738596112✅ Call Girl Andheri East G...
 
SIKP311 Sikolohiyang Pilipino - Ginhawa.pptx
SIKP311 Sikolohiyang Pilipino - Ginhawa.pptxSIKP311 Sikolohiyang Pilipino - Ginhawa.pptx
SIKP311 Sikolohiyang Pilipino - Ginhawa.pptx
 
Emotional Freedom Technique Tapping Points Diagram.pdf
Emotional Freedom Technique Tapping Points Diagram.pdfEmotional Freedom Technique Tapping Points Diagram.pdf
Emotional Freedom Technique Tapping Points Diagram.pdf
 
March 2023 Recommendations for newsletter
March 2023 Recommendations for newsletterMarch 2023 Recommendations for newsletter
March 2023 Recommendations for newsletter
 

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

  • 1. Cypher: Como a query language do Neo4j foi construída e como usá-la tldr: Cypher internals em 15 minutos
  • 3. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
  • 4. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
  • 5. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
  • 6. Quem é vc? Adriano Almeida @adrianoalmeida7 ahalmeida.com
  • 8. Buscando dados no Neo4j 1. Traverse API Clássica
  • 9. Buscando dados no Neo4j 1. Traverse API Clássica private 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. Buscando dados no Neo4j 2. Traverse API Nova
  • 11. Buscando dados no Neo4j 2. Traverse API Nova private 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. Buscando dados no Neo4j 3. Cypher
  • 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. Buscando dados no Neo4j 3. Cypher private 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. Buscando dados no Neo4j 3. Cypher - Parsing - Execução
  • 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 10 Skip & Limit
  • 17. Por partes: Start Clause start ::= "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. Por partes: Start Clause Como implementar o parser disso?
  • 19. Por partes: Start Clause Scala + Parser Combinators
  • 20. Por partes: Start Clause package org.neo4j.cypher.parser trait 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. Por partes: Start Clause package org.neo4j.cypher.parser trait 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. Por partes: Start Clause package org.neo4j.cypher.parser trait 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. Por partes: Start Clause package org.neo4j.cypher.parser trait 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. AST Query.scala package org.neo4j.cypher.commands case class Start(startItems: StartItem*) StartItem.scala package org.neo4j.cypher.commands abstract 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. Por partes: Outras Clauses (não dá tempo) http://chu.pe/8K
  • 26. Toda a query package org.neo4j.cypher.parser class 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) } }
  • 30. Pipes StartPipe -> MatchPipe -> NamedPathPipe
  • 31. Pipes StartPipe -> MatchPipe -> NamedPathPipe -> FilterPipe
  • 32. Pipes StartPipe -> MatchPipe -> NamedPathPipe -> FilterPipe -> TransformPipe (Aggregation, Sort & Slice)
  • 33. Pipes StartPipe -> MatchPipe -> NamedPathPipe -> FilterPipe -> TransformPipe (Aggregation, Sort & Slice) -> ColumnFilterPipe
  • 34.
  • 35. Prós e Contras + Objetiva + Ops Friendly + Poderosa (algoritmos de grafos e pattern matching) - Verbosa - Performance (ainda) +/- Work In Progress
  • 36. Explicação mais detalhada • http://ahalmeida.com/

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n