Aggregator SumField

41 views
Skip to first unread message

Olivier Droz

unread,
Nov 23, 2015, 3:55:16 PM11/23/15
to ReactiveMongo - http://reactivemongo.org
Hi There, 
I have a collection of prospects that have the following structure:

case class Prospect(

  id_prospect: String, //UUID

  projectUUID: String

  email: Option[String],

  firstName: Option[String], 

  middleName: Option[String], 

  lastName: Option[String], 

  cookie: String,

  leadStatus: LeadStatus,

  visits: List[Visit],

  temperature: Temperature,

  notes: String,

  favorite: Boolean, 

  assignee: Option[SwUser], 

  lastFavoriteNotificationDate: Option[DateTime] = None

  wasEverHot: Option[Boolean] = Some(false)

)


I'm trying to get some Stats using the Aggregation Framework.

Basically I want to get the number of Prospect per projectUUID given the leadStatus.


In MongoShell, I can do this: db.prospects.aggregate([{$group:{_id:"$projectUUID", totalLead:{$sum:{$add:1}}}}])


I created a case class:

case class ProspectStats(projectUUID: String, leadCount: Int)

object ProspectStats{

implicit val reader = Macros.reader[ProspectStats]  

}


and a Aggregator Function:



  def getProjectLeadStatsAggregate(col: BSONCollection, leadType: String): Future[List[ProspectStats]] = {

    import col.BatchCommands.AggregationFramework.{

      AggregationResult,

      Group,

      Match,

      SumValue

    }

    val res: Future[AggregationResult] = col.aggregate(

      Group(BSONString("$_id"))("totalLead" -> SumValue(1)))

    res.map(_.result[ProspectStats])

  }



But I keep getting a DocumentKeyNotFound exception on Macros.reader

[DocumentKeyNotFound: The key 'projectUUID' could not be found in this document or array]


case class ProspectStats(projectUUID: String, leadCount: Int)
32object ProspectStats{
33implicit val reader = Macros.reader[ProspectStats]  
34}

Olivier Droz

unread,
Nov 23, 2015, 4:31:28 PM11/23/15
to ReactiveMongo - http://reactivemongo.org
Sorry, I post it before the end of my question...

I tried with a custom BSONDocumentReader as well, but can't get it working.

How can I translate this:

db.prospects.aggregate([{$group:{_id:"$projectUUID", totalLead:{$sum:{$add:1}}}}])

into a reactiveMongo syntax.

Is using the aggregator framework a good solution? Any other?

Thanks a lot for your inputs.

Olivier

Cédric Chantepie

unread,
Dec 18, 2015, 7:34:16 AM12/18/15
to ReactiveMongo - http://reactivemongo.org

Olivier Droz

unread,
Jan 13, 2016, 2:24:13 AM1/13/16
to reacti...@googlegroups.com
Hi Cedric, 
Thanks, I carefully followed the documentation, but I think my problem is that I can't get the BSONDocument into a "ProspectStats" (case class). I keep trying to transform a list of BSONDocument(<non-empty>) into a list of ProspectStats. 

In the AggregatorResult, I tried using "documents" instead of "result" and transform the document into stream to see what's inside and I actually get a List of Stream of  tuple Success...

List(Stream(Success((_id,BSONString(acab62ad-597e-4918-86bb-df3c85d4817a))), Success((totalLead,BSONInteger(1)))))

I'm using "org.reactivemongo" %% "play2-reactivemongo" % "0.11.7.play23", (play 2.3.9) 

Do you know some other good code example that I could follow? Couldn't find much on gitHub.

Thanks a lot, 


Olivier


Olivier Droz
Ing. Inf. Dipl. EPF
Rte de la Feuillère 29
1010 Lausanne

On Fri, Dec 18, 2015 at 1:34 PM, Cédric Chantepie <chantep...@gmail.com> wrote:

--
You received this message because you are subscribed to a topic in the Google Groups "ReactiveMongo - http://reactivemongo.org" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/reactivemongo/Dee6qJOkZak/unsubscribe.
To unsubscribe from this group and all its topics, send an email to reactivemong...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Cédric Chantepie

unread,
Jan 13, 2016, 6:48:15 PM1/13/16
to ReactiveMongo - http://reactivemongo.org
What's the error? As soon as there is a reader for T, you can use .result[T] on aggregation result.

Olivier Droz

unread,
Jan 15, 2016, 5:16:20 AM1/15/16
to reacti...@googlegroups.com
Thanks Cédric for your quick answer. 
I finally found the issue.
I was looking for the key "projectUUID" as I defined in my aggregator, however this value is returned under the key "_id"
I wrote my reader as bellow and it works fine:

case class ProspectStats(projectUUID: String, leadCount: Int)

object ProspectStats{

  implicit object ProspectBSONReader extends BSONDocumentReader[ProspectStats] {

    def read(doc: BSONDocument): ProspectStats ={

      ProspectStats(

          doc.getAs[BSONString]("_id").get.as[String],

          doc.getAs[BSONInteger]("totalLead").get.as[Int]

      )

    }

  } 

}


Thanks a lot for your help!


Olivier




Olivier Droz
Ing. Inf. Dipl. EPF
Rte de la Feuillère 29
1010 Lausanne

On Thu, Jan 14, 2016 at 12:48 AM, Cédric Chantepie <chantep...@gmail.com> wrote:
What's the error? As soon as there is a reader for T, you can use .result[T] on aggregation result.
Reply all
Reply to author
Forward
0 new messages