Skip to content

Instantly share code, notes, and snippets.

@ojacquemart
Last active December 15, 2015 01:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ojacquemart/5183374 to your computer and use it in GitHub Desktop.
Save ojacquemart/5183374 to your computer and use it in GitHub Desktop.
Mongo M101J: Week3#Exercise1
package tengen
import play.api._
import play.api.libs.json._
import play.api.mvc._
import play.api.Logger
import play.api.Play.current
import play.modules.reactivemongo._
import play.modules.reactivemongo.ReactiveMongoPlugin
import org.joda.time.DateTime
import reactivemongo.bson._
import reactivemongo.bson.handlers.DefaultBSONHandlers.DefaultBSONDocumentWriter
import reactivemongo.bson.handlers.DefaultBSONHandlers.DefaultBSONReaderHandler
import reactivemongo.bson._
import reactivemongo.bson.handlers._
import scala.concurrent.{ExecutionContext, Future}
import ExecutionContext.Implicits.global
/*
> db.students.find({_id:100}).pretty()
{
"_id" : 100,
"name" : "Demarcus Audette",
"scores" : [
{
"type" : "exam",
"score" : 30.61740640636871
},
{
"type" : "quiz",
"score" : 14.23233821353732
},
{
"type" : "homework",
"score" : 31.41421298576332
},
{
"type" : "homework",
"score" : 30.09304792394713
}
]
}
*/
case class Score(examType: String, score: Double)
case class Student(id: Option[BSONInteger], name: String, var scores: List[Score])
object ScoreBSON {
implicit object Reader extends BSONReader[Score] {
def fromBSON(document: BSONDocument): Score = {
val doc = document.toTraversable
val score = Score(
doc.getAs[BSONString]("type").get.value,
doc.getAs[BSONDouble]("score").get.value)
score
}
}
implicit object Writer extends BSONWriter[Score] {
def toBSON(score: Score) = {
BSONDocument(
"type" -> BSONString(score.examType),
"score" -> BSONDouble(score.score)
)
}
}
}
class BsonReaderHelper(doc: TraversableBSONDocument) {
def document[T](fieldName: String)(implicit reader: BSONReader[T]) = {
reader.fromBSON(doc.getAs[BSONDocument](fieldName).get)
}
def listDocument[T](fieldName: String)(implicit reader: BSONReader[T]) = {
doc.getAs[BSONArray](fieldName).get.toTraversable.toList.map {
t =>
reader.fromBSON(t.asInstanceOf[TraversableBSONDocument])
}
}
def date(fieldName: String) = doc.getAs[BSONDateTime](fieldName).map(dt => new DateTime(dt.value))
}
class BsonWriterHelper() {
def listDocument[T](xs: List[T])(implicit writer: BSONWriter[T]) = {
BSONArray(xs.map {
t => writer.toBSON(t)
}: _*)
}
def document[T](doc: T)(implicit writer: BSONWriter[T]) = writer.toBSON(doc)
}
object StudentBSON {
implicit object Reader extends BSONReader[Student] {
def fromBSON(document: BSONDocument): Student = {
val doc = document.toTraversable
def listDocument[T](fieldName: String)(implicit reader: BSONReader[T]) = {
doc.getAs[BSONArray](fieldName).get.toTraversable.toList.map {
t =>
reader.fromBSON(t.asInstanceOf[TraversableBSONDocument])
}
}
implicit val scoreReader = ScoreBSON.Reader
val scores = listDocument[Score]("scores")
val student = Student(
doc.getAs[BSONInteger]("_id"),
doc.getAs[BSONString]("name").get.value,
scores)
student
}
}
implicit object Writer extends BSONWriter[Student] {
def toBSON(student: Student) = {
val helper = new BsonWriterHelper()
implicit val scoreWriter = ScoreBSON.Writer
BSONDocument(
"_id" -> student.id.get,
"name" -> BSONString(student.name),
"scores" -> helper.listDocument(student.scores)
)
}
}
}
object Week3 {
def db = ReactiveMongoPlugin.db
def collection = db("students")
def getStudentById(id: Int) = {
implicit val reader = StudentBSON.Reader
val selector = BSONDocument("_id" -> BSONInteger(id))
collection.find(selector).toList
}
def insert(students: List[Student]) = {
implicit val studentWriter = StudentBSON.Writer
students.foreach(student => {
val id = student.id.get.value
collection.update(BSONDocument("_id" -> BSONInteger(id)), student)
})
}
def removeLowerHomeworkScore() = {
implicit val reader = StudentBSON.Reader
val selector = BSONDocument()
val query = collection.find(selector)
val list = query.toList()
list onSuccess {
case students => {
students.foreach(student => {
val partitionScores = student.scores.partition(score => score.examType != "homework")
val homeworks = partitionScores._2.sortBy(_.score).tail
student.scores = partitionScores._1 ++ homeworks
})
}
}
list
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment