18
Abdhesh Kumar [email protected] Type-Safe Mongo Query (Rogue Query)

Type-Safe MongoDB query (Lift Rogue query)

Embed Size (px)

DESCRIPTION

Type-safe query is internal Scala DSL for constructing and executing find and modify commands against MongoDB in the Lift web framework.

Citation preview

Page 1: Type-Safe MongoDB query (Lift Rogue query)

Abdhesh [email protected]

Type-Safe Mongo Query(Rogue Query)

Page 2: Type-Safe MongoDB query (Lift Rogue query)

1. What is type-safe?

2. What is Mongo Record?

3. What is native Mongo query?

4.What is the Rogue query?

5. Installation

6. SetUp

7. Query Examples

Agenda

Page 3: Type-Safe MongoDB query (Lift Rogue query)

What is Type-safe?-> It’s type safe meaning, for example, if you try to use an Int

where a String is expected in a function or query.

A type error is erroneous or undesirable program behaviour caused by a discrepancy

between differing data types for the program's constants, variables, and methods

(functions), e.g., treating an integer (int) as a floating-point number (float)

def typeSafeFunction(param: String): Unit ={....}

You can not call this function by passing any value other than String

ex. typeSafeFunction(23),typeSafeFunction(43.3434),typeSafeFunction(User)

Page 4: Type-Safe MongoDB query (Lift Rogue query)

Mongo Record

Mongo Record is ORM layer for Lift. Lift’s Record class represents

a database record(mongo collections), and MetaRecord trait provides “static” methods for querying and updating records in a

fully expressive way.

Page 5: Type-Safe MongoDB query (Lift Rogue query)

Mongo Record...

object Student extends Student with MongoMetaRecord[Student]

class Student extends MongoRecord[Student] with ObjectIdPk[Student] {

def meta: Student.type = Student

object name extends StringField(this, 200)

object age extends IntField(this)

object address extends StringField(this, 200)

object scores extends BsonRecordListField(this, Score)

def toJson = this.asJSON}

Page 6: Type-Safe MongoDB query (Lift Rogue query)

Mongo Record...

object Score extends Score with BsonMetaRecord[Score]

class Score extends BsonRecord[Score] { def meta: Score.type = Score object examtype extends StringField(this, 50)

object score extends DoubleField(this)}

Page 7: Type-Safe MongoDB query (Lift Rogue query)

Mongo Query

1. find all documents db.students.find()

2. find student that has age 20 yearsdb.students.find({age:20})

3. find students that has more than 25 yearsdb.students.find({age:{"$gte":25}})

4. find students that has more than 40% in quiz

db.students.find({"scores":{"$elemMatch"{"score":"$gt":40},"examtype":"quiz"}}})

Page 8: Type-Safe MongoDB query (Lift Rogue query)

Scala Query Againts MongodbLift’s MongoMetaRecord trait provides a findAll() method that lets you pass in a query as a JSON object (MongoDB queries are in fact JSON objects), returning a list of records.

For example, using lift’s JsonDSL, we can do:Student.findAll((Student.name.name -> "Bao Ziglar") ~ (Student.age.name ->( “$gt”->25)))

which is equivalent to

Student.findAll("{ name : “Bao Ziglar”, age : { $gt : 25 } }")

BUTThis would also run by mongo server

Student.findAll((Student.name.name -> "Bao Ziglar") ~ (Student.age.name -> “Farji25”))It's not a valid query and it happily executes for you, returning nothing, never informing you that the age field is not a String but a Int representing the age of the Student.

Page 9: Type-Safe MongoDB query (Lift Rogue query)

Typesafe Query->There should be someting here that enforce to use query in typesafe sense

-> Scala compiler should detected field type againts records, fields, conditions and Operands

Student.where(_.name eqs “studentName”).and(_.age eqs "Farji25").fetch

It through the scala error type mismatch; found : String("Farji25") required: Int

Mongo would allow that query and fail to find results at runtime, but Rogue enables Scala to reject the query at compile time.

Page 10: Type-Safe MongoDB query (Lift Rogue query)

Rogue Query(Typesafe query)

-> Rogue is a type-safe internal Scala DSL for constructing and executing find and modify commands against MongoDB in the Lift web framework.

-> It is fully expressive with respect to the basic options provided by MongoDB's native query language, but in a type-safe manner

-> Rogue was initially developed by Foursquare Labs for internal use nearly all of the MongoDB queries in foursquare's code base go through this library.

Page 11: Type-Safe MongoDB query (Lift Rogue query)

Rogue Query(Typesafe query)...

The Rogue query (typesafe query) enforces the following Constraints:

->The fields must actually belong to the record (e.g., age is a field on the Student record)

->The field type must match the operand type (e.g., age is an IntField)

-> The operator must make sense for the field type (e.g., scores is a MongoListField[String])

->The value specified in the query clause is the same type as the field type (or is appropriate for the operator)

Page 12: Type-Safe MongoDB query (Lift Rogue query)

Installation

val rogueField = "com.foursquare" %% "rogue field" % "2.2.0" intransitive()

val rogueCore = "com.foursquare" %% "rogue core" % "2.2.0" intransitive()

val rogueLift = "com.foursquare" %% "rogue lift" % "2.2.0" intransitive()

val rogueIndex = "com.foursquare" %% "rogue index" % "2.2.0" intransitive()

val liftMongoRecord = "net.liftweb" %% "lift mongodb record" % "2.4"

Page 13: Type-Safe MongoDB query (Lift Rogue query)

SetUp and Typesafe query

Import package:import com.foursquare.rogue.LiftRogue._

Typesafe query:

Student.where(_.name eqs stdName).and(_.age eqs 25).fetch

Student.where(_.name eqs stdName).

and(_.scores elemMatch (_.score gte 25, _.examtype eqs "quiz")).fetch

Page 14: Type-Safe MongoDB query (Lift Rogue query)

Rogue QueryImport package:

import com.foursquare.rogue.LiftRogue._

Typesafe query:

Student.where(_.name eqs stdName).and(_.age eqs 25).fetch

equivalent to:

db.students.find({ "name" : "stdName" , "age" : 25})

Student.where(_.name eqs stdName).and(_.scores elemMatch (_.score gte 25, _.examtype eqs "quiz")).fetch

equivalent to:

db.students.find({ "name" : "stdName" , "scores" : { "$elemMatch" : { "examtype" : "quiz" , "score" : { "$gte" : 25.0}}}})

Page 15: Type-Safe MongoDB query (Lift Rogue query)

Rogue Query..

Student.where(_.name matches Pattern.compile(Pattern.quote(stdName), Pattern.CASE_INSENSITIVE | Pattern.MULTILINE)).fetch

Equivalent :

db.students.find({ "name" : { "$regex" : "\\QstdName\\E" , "$options" : "im"}})

Page 16: Type-Safe MongoDB query (Lift Rogue query)

Rogue support.

Type safe rogue support all mongodb operators:

Like. Eqs, neq,lt,gt,in,nin,exists,startsWith, regex,all, in, size, contains, at

,BsonRecordField subfield queries

Page 17: Type-Safe MongoDB query (Lift Rogue query)

References

http://engineering.foursquare.com/2011/01/21/rogue-a-type-safe-scala-dsl-for-querying-mongodb/

https://github.com/foursquare/rogue

Page 18: Type-Safe MongoDB query (Lift Rogue query)

Thanks