SlideShare une entreprise Scribd logo
1  sur  36
Télécharger pour lire hors ligne
rogue:
a scala dsl for mongodb
ScalaDays 2011 - 6/2/2011
Jason Liszka (@jliszka)
Jorge Ortiz (@jorgeortiz85)
what is foursquare?
location-based social network - “check-in” to bars,
restaurants, museums, parks, etc
  friend-finder (where are my friends right now?)
  virtual game (badges, points, mayorships)
  city guide (local, personalized recommendations)
  location diary + stats engine (where was I a year ago?)
  specials (get rewards at your favorite restaurant)
foursquare: the numbers

>9M users
~3M checkins/day
>15M venues
>400k merchants
>60 employees
foursquare: the tech

 Nginx, HAProxy
 Scala, Lift
 MongoDB, PostgreSQL (legacy)
 (Kestrel, Munin, Ganglia, Python, Memcache, ...)
 All on EC2
what is mongodb?

fast, schema-less document store
indexes & rich queries on any field
sharding, auto-balancing
replication
geo-indexes
mongodb: our numbers

8 clusters
  some sharded, some not
  some master/slave, some replica set
~40 machines (68.4GB, m2.4xl on EC2)
2.3 billion records
~15k QPS
mongodb: bson
json++
binary wire format
more built-in types:
  objectid
  date
  regex
  bina
mongodb: bson example

{
    “_id” :
      { “oid” : “4ddbd194686148110d5c1ccc” },
    “venuename” : “Starbucks”,
    “mayorid” : 464,
    “tags” : [“coffee”, “wifi”, “snacks”],
    “latlng” : [39.0, -74.0]
}
mongodb: query example
{
    “mayorid” : { “$lte” : 100 },
    “venuename” : “Starbucks”,
    “tags” : “wifi”,
    “latlng” : { “$near” : [39.0, -74.0] }
}

{ “_id” : -1 }
mongodb: query example
val query =
  (BasicDBOBjectBuilder
    .start
    .push(“mayorid”)
      .add(“$lte”, 100)
    .pop
    .add(“veneuname”, “Starbucks”)
    ...
    .get)
rogue: a scala dsl for mongo

 type-safe
 all mongo query features
 logging & validation hooks
 pagination
 index-aware
 cursors
           http://github.com/foursquare/rogue
rogue: schema example
class Venue extends MongoRecord[Venue] {
  object _id extends ObjectIdField(this)
  object venuename extends StringField(this)
  object mayorid extends LongField(this)
  object tags extends ListField[String](this)
  object latlng extends LatLngField(this)
}

object Venue extends Venue
                with MongoMetaRecord[Venue]
rogue: code example

val vs: List[Venue] =
  (Venue where (_.mayorid <= 100)
          and (_.venuename eqs “Starbucks”)
          and (_.tags contains “wifi”)
          and (_.latlng near
                (39.0, -74.0, Degrees(0.2))
    orderDesc (_._id)
        fetch (5))
rogue: BaseQuery

class BaseQuery[M <: MongoRecord[M], R,
                Ord, Sel, Lim, Sk](...) {

    def where[F](clause: M => QueryClause[F]): ...

    ...
}
rogue: QueryField

class QueryField[V, M <: MongoRecord[M]]
                (val field: Field[V, M]) {
  def eqs(v: V) = new EqClause(...)
  def neqs(v: V) = ...
  def in[L <% List[V]](vs: L) = ...
  def nin[L <% List[V]](vs: L) = ...
  def exists(b: Boolean) = ...
}
rogue: implicits

Field[F, M] => QueryField[F, M]
Field[LatLong, M] => GeoQueryField[M]
Field[List[F], M] => ListQueryField[F, M]
Field[String, M] => StringQueryField[M]
Field[Int, M] => NumericQueryField[Int, M]
Field[Double, M] => NumericQueryField[Double, M]
...
rogue: select


val vs: List[(Long, Int)] =
  (Venue where (_.venuename eqs “Starbucks”)
        select (_.mayorid, _.mayorCheckins)
         fetch ())
rogue: select
class BaseQuery[M <: MongoRecord[M], R,
                Ord, Sel, Lim, Sk](...) {

    def select[F1, F2](
      f1: M => Field[F1, M],
      f2: M => Field[F2, M]):
        BaseQuery[M, (F1, F2), ...] = ...

    ...
}
rogue: select problems


val vs: List[???] =
  (Venue where (_.venuename eqs “Starbucks”)
        select (_.mayorid, _.mayorCheckins)
        select (_.venuename)
         fetch ())
rogue: limit problems


val vs: List[Venue] =
  (Venue where (_.venuename eqs “Starbucks”)
         limit (5)
         limit (100)   // (???)
         fetch ())
rogue: more limit problems

(Venue where (_.venuename eqs “Starbucks”)
       orderAsc (_.total_checkins)
       limit (5)
       bulkDelete_!!)

// How many Venues got deleted?
rogue: phantom types


     Sel =:= Selected, Unselected
     Ord =:= Ordered, Unordered
     Lim =:= Limited, Unlimited
     Sk =:= Skipped, Unskipped



http://james-iry.blogspot.com/2010/10/phantom-types-in-haskell-and-scala.html
rogue: phantom types

abstract   sealed   class   Ordered
abstract   sealed   class   Unordered
abstract   sealed   class   Selected
abstract   sealed   class   Unselected
abstract   sealed   class   Limited
abstract   sealed   class   Unlimited
abstract   sealed   class   Skipped
abstract   sealed   class   Unskipped
rogue: initializing phantoms
class BaseQuery[M <: MongoRecord[M], R,
                Ord, Sel, Lim, Sk](...) {
  ...
}

def dfltQuery[M <: MongoRecord[M]](rec: M) =
  new BaseQuery[M, M,
                Unordered,
                Unselected,
                Unlimited,
                Unskipped](...)
rogue: select phantom
class BaseQuery[M <: MongoRecord[M], R,
                Ord, Sel, Lim, Sk](...) {

    def select[F1, F2](
      f1: M => Field[F1, M],
      f2: M => Field[F2, M])
     (implicit ev: Sel =:= Unselected):
        BaseQuery[M, (F1, F2),
                  Ord, Selected, Lim, Sk] = ...
    ...
}
rogue: =:=


sealed abstract class =:=[From, To] ...

implicit def tpEquals[A]: A =:= A = ...
rogue: select solutions

val vs: List[???] =
  (Venue where (_.venuename eqs “Starbucks”)
        select (_.mayorid, _.mayorCheckins)
        select (_.venuename)
         fetch ())

// won’t compile!
rogue: limit solutions

(Venue where (_.venuename eqs “Starbucks”)
       orderAsc (_.total_checkins)
       limit (5)
       bulkDelete_!!)

// won’t compile!
rogue: index-aware


val vs: List[Checkin] =
  (Checkin
    where (_.userid eqs 646)
      and (_.venueid eqs vid)
    fetch ())
rogue: index-aware


val vs: List[Checkin] =
  (Checkin
    where (_.userid eqs 646)
      and (_.venueid eqs vid) // hidden scan!
    fetch ())
rogue: index-aware


val vs: List[Checkin] =
  (Checkin
    where (_.userid eqs 646) // known index
     scan (_.venueid eqs vid) // known scan
    fetch ())
rogue: logging & validation

 logging:
   slf4j
   Tracer
 validation:
   radius, $in size
   index checks
rogue: pagination

val query: Query[Venue] = ...

val vs: List[Venue] =
  (query
    .countPerPage(20)
    .setPage(5)
    .fetch())
rogue: cursors


val query: Query[Checkin] = ...

for (checkin <- query) {
  ... f(checkin) ...
}
rogue: future directions


 iteratees for cursors
 compile-time index checking
 select partial objects
 generate full javascript for mapreduce
we’re hiring
    (nyc & sf)
http://foursquare.com/jobs
  @jliszka, @jorgeortiz85

Contenu connexe

Tendances

PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)Nikita Popov
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applicationsSkills Matter
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212Mahmoud Samir Fayed
 
Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwoEishay Smith
 
The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84Mahmoud Samir Fayed
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門Hiromi Ishii
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonUC San Diego
 
ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1RORLAB
 
[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기NAVER D2
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala LanguageAshal aka JOKER
 
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...Databricks
 
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...Matthew Tovbin
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jqueryDanilo Sousa
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)Nikita Popov
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2RORLAB
 
The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202Mahmoud Samir Fayed
 
Using spark data frame for sql
Using spark data frame for sqlUsing spark data frame for sql
Using spark data frame for sqlDaeMyung Kang
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Suyeol Jeon
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickHermann Hueck
 

Tendances (20)

PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212The Ring programming language version 1.10 book - Part 47 of 212
The Ring programming language version 1.10 book - Part 47 of 212
 
Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwo
 
The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84The Ring programming language version 1.2 book - Part 19 of 84
The Ring programming language version 1.2 book - Part 19 of 84
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1ActiveRecord Query Interface (1), Season 1
ActiveRecord Query Interface (1), Season 1
 
[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기[131]해커의 관점에서 바라보기
[131]해커의 관점에서 바라보기
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language
 
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
 
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
 
Iniciando com jquery
Iniciando com jqueryIniciando com jquery
Iniciando com jquery
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)PHP 7 – What changed internally? (PHP Barcelona 2015)
PHP 7 – What changed internally? (PHP Barcelona 2015)
 
Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2Active Record Query Interface (1), Season 2
Active Record Query Interface (1), Season 2
 
The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202The Ring programming language version 1.8 book - Part 50 of 202
The Ring programming language version 1.8 book - Part 50 of 202
 
Using spark data frame for sql
Using spark data frame for sqlUsing spark data frame for sql
Using spark data frame for sql
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
 
P5
P5P5
P5
 
Implementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with SlickImplementing a many-to-many Relationship with Slick
Implementing a many-to-many Relationship with Slick
 

Similaire à Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDB

MongoSF - mongodb @ foursquare
MongoSF - mongodb @ foursquareMongoSF - mongodb @ foursquare
MongoSF - mongodb @ foursquarejorgeortiz85
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Apache Spark for Library Developers with William Benton and Erik Erlandson
 Apache Spark for Library Developers with William Benton and Erik Erlandson Apache Spark for Library Developers with William Benton and Erik Erlandson
Apache Spark for Library Developers with William Benton and Erik ErlandsonDatabricks
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme SwiftMovel
 
Getting Functional with Scala
Getting Functional with ScalaGetting Functional with Scala
Getting Functional with ScalaJorge Paez
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class PatternsJohn De Goes
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Codestasimus
 
Scala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldWerner Hofstra
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)MongoSF
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomerzefhemel
 
Scala for the web Lightning Talk
Scala for the web Lightning TalkScala for the web Lightning Talk
Scala for the web Lightning TalkGiltTech
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - GuilinJackson Tian
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveJeff Smith
 

Similaire à Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDB (20)

MongoSF - mongodb @ foursquare
MongoSF - mongodb @ foursquareMongoSF - mongodb @ foursquare
MongoSF - mongodb @ foursquare
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Apache Spark for Library Developers with William Benton and Erik Erlandson
 Apache Spark for Library Developers with William Benton and Erik Erlandson Apache Spark for Library Developers with William Benton and Erik Erlandson
Apache Spark for Library Developers with William Benton and Erik Erlandson
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Getting Functional with Scala
Getting Functional with ScalaGetting Functional with Scala
Getting Functional with Scala
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
First-Class Patterns
First-Class PatternsFirst-Class Patterns
First-Class Patterns
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
Scala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereldScala: Functioneel programmeren in een object georiënteerde wereld
Scala: Functioneel programmeren in een object georiënteerde wereld
 
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
Map/reduce, geospatial indexing, and other cool features (Kristina Chodorow)
 
mobl presentation @ IHomer
mobl presentation @ IHomermobl presentation @ IHomer
mobl presentation @ IHomer
 
Message in a bottle
Message in a bottleMessage in a bottle
Message in a bottle
 
Scala for the web Lightning Talk
Scala for the web Lightning TalkScala for the web Lightning Talk
Scala for the web Lightning Talk
 
Spark workshop
Spark workshopSpark workshop
Spark workshop
 
Mongoskin - Guilin
Mongoskin - GuilinMongoskin - Guilin
Mongoskin - Guilin
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 

Scala Days 2011 - Rogue: A Type-Safe DSL for MongoDB

  • 1. rogue: a scala dsl for mongodb ScalaDays 2011 - 6/2/2011 Jason Liszka (@jliszka) Jorge Ortiz (@jorgeortiz85)
  • 2. what is foursquare? location-based social network - “check-in” to bars, restaurants, museums, parks, etc friend-finder (where are my friends right now?) virtual game (badges, points, mayorships) city guide (local, personalized recommendations) location diary + stats engine (where was I a year ago?) specials (get rewards at your favorite restaurant)
  • 3. foursquare: the numbers >9M users ~3M checkins/day >15M venues >400k merchants >60 employees
  • 4. foursquare: the tech Nginx, HAProxy Scala, Lift MongoDB, PostgreSQL (legacy) (Kestrel, Munin, Ganglia, Python, Memcache, ...) All on EC2
  • 5. what is mongodb? fast, schema-less document store indexes & rich queries on any field sharding, auto-balancing replication geo-indexes
  • 6. mongodb: our numbers 8 clusters some sharded, some not some master/slave, some replica set ~40 machines (68.4GB, m2.4xl on EC2) 2.3 billion records ~15k QPS
  • 7. mongodb: bson json++ binary wire format more built-in types: objectid date regex bina
  • 8. mongodb: bson example { “_id” : { “oid” : “4ddbd194686148110d5c1ccc” }, “venuename” : “Starbucks”, “mayorid” : 464, “tags” : [“coffee”, “wifi”, “snacks”], “latlng” : [39.0, -74.0] }
  • 9. mongodb: query example { “mayorid” : { “$lte” : 100 }, “venuename” : “Starbucks”, “tags” : “wifi”, “latlng” : { “$near” : [39.0, -74.0] } } { “_id” : -1 }
  • 10. mongodb: query example val query = (BasicDBOBjectBuilder .start .push(“mayorid”) .add(“$lte”, 100) .pop .add(“veneuname”, “Starbucks”) ... .get)
  • 11. rogue: a scala dsl for mongo type-safe all mongo query features logging & validation hooks pagination index-aware cursors http://github.com/foursquare/rogue
  • 12. rogue: schema example class Venue extends MongoRecord[Venue] { object _id extends ObjectIdField(this) object venuename extends StringField(this) object mayorid extends LongField(this) object tags extends ListField[String](this) object latlng extends LatLngField(this) } object Venue extends Venue with MongoMetaRecord[Venue]
  • 13. rogue: code example val vs: List[Venue] = (Venue where (_.mayorid <= 100) and (_.venuename eqs “Starbucks”) and (_.tags contains “wifi”) and (_.latlng near (39.0, -74.0, Degrees(0.2)) orderDesc (_._id) fetch (5))
  • 14. rogue: BaseQuery class BaseQuery[M <: MongoRecord[M], R, Ord, Sel, Lim, Sk](...) { def where[F](clause: M => QueryClause[F]): ... ... }
  • 15. rogue: QueryField class QueryField[V, M <: MongoRecord[M]] (val field: Field[V, M]) { def eqs(v: V) = new EqClause(...) def neqs(v: V) = ... def in[L <% List[V]](vs: L) = ... def nin[L <% List[V]](vs: L) = ... def exists(b: Boolean) = ... }
  • 16. rogue: implicits Field[F, M] => QueryField[F, M] Field[LatLong, M] => GeoQueryField[M] Field[List[F], M] => ListQueryField[F, M] Field[String, M] => StringQueryField[M] Field[Int, M] => NumericQueryField[Int, M] Field[Double, M] => NumericQueryField[Double, M] ...
  • 17. rogue: select val vs: List[(Long, Int)] = (Venue where (_.venuename eqs “Starbucks”) select (_.mayorid, _.mayorCheckins) fetch ())
  • 18. rogue: select class BaseQuery[M <: MongoRecord[M], R, Ord, Sel, Lim, Sk](...) { def select[F1, F2]( f1: M => Field[F1, M], f2: M => Field[F2, M]): BaseQuery[M, (F1, F2), ...] = ... ... }
  • 19. rogue: select problems val vs: List[???] = (Venue where (_.venuename eqs “Starbucks”) select (_.mayorid, _.mayorCheckins) select (_.venuename) fetch ())
  • 20. rogue: limit problems val vs: List[Venue] = (Venue where (_.venuename eqs “Starbucks”) limit (5) limit (100) // (???) fetch ())
  • 21. rogue: more limit problems (Venue where (_.venuename eqs “Starbucks”) orderAsc (_.total_checkins) limit (5) bulkDelete_!!) // How many Venues got deleted?
  • 22. rogue: phantom types Sel =:= Selected, Unselected Ord =:= Ordered, Unordered Lim =:= Limited, Unlimited Sk =:= Skipped, Unskipped http://james-iry.blogspot.com/2010/10/phantom-types-in-haskell-and-scala.html
  • 23. rogue: phantom types abstract sealed class Ordered abstract sealed class Unordered abstract sealed class Selected abstract sealed class Unselected abstract sealed class Limited abstract sealed class Unlimited abstract sealed class Skipped abstract sealed class Unskipped
  • 24. rogue: initializing phantoms class BaseQuery[M <: MongoRecord[M], R, Ord, Sel, Lim, Sk](...) { ... } def dfltQuery[M <: MongoRecord[M]](rec: M) = new BaseQuery[M, M, Unordered, Unselected, Unlimited, Unskipped](...)
  • 25. rogue: select phantom class BaseQuery[M <: MongoRecord[M], R, Ord, Sel, Lim, Sk](...) { def select[F1, F2]( f1: M => Field[F1, M], f2: M => Field[F2, M]) (implicit ev: Sel =:= Unselected): BaseQuery[M, (F1, F2), Ord, Selected, Lim, Sk] = ... ... }
  • 26. rogue: =:= sealed abstract class =:=[From, To] ... implicit def tpEquals[A]: A =:= A = ...
  • 27. rogue: select solutions val vs: List[???] = (Venue where (_.venuename eqs “Starbucks”) select (_.mayorid, _.mayorCheckins) select (_.venuename) fetch ()) // won’t compile!
  • 28. rogue: limit solutions (Venue where (_.venuename eqs “Starbucks”) orderAsc (_.total_checkins) limit (5) bulkDelete_!!) // won’t compile!
  • 29. rogue: index-aware val vs: List[Checkin] = (Checkin where (_.userid eqs 646) and (_.venueid eqs vid) fetch ())
  • 30. rogue: index-aware val vs: List[Checkin] = (Checkin where (_.userid eqs 646) and (_.venueid eqs vid) // hidden scan! fetch ())
  • 31. rogue: index-aware val vs: List[Checkin] = (Checkin where (_.userid eqs 646) // known index scan (_.venueid eqs vid) // known scan fetch ())
  • 32. rogue: logging & validation logging: slf4j Tracer validation: radius, $in size index checks
  • 33. rogue: pagination val query: Query[Venue] = ... val vs: List[Venue] = (query .countPerPage(20) .setPage(5) .fetch())
  • 34. rogue: cursors val query: Query[Checkin] = ... for (checkin <- query) { ... f(checkin) ... }
  • 35. rogue: future directions iteratees for cursors compile-time index checking select partial objects generate full javascript for mapreduce
  • 36. we’re hiring (nyc & sf) http://foursquare.com/jobs @jliszka, @jorgeortiz85

Notes de l'éditeur

  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