Reputation: 932
I'm using reactivemongo with play framework. I used to have a query which uses the aggregation framework and it worked as expected. Since updated to version 0.13.0 I get errors executing the query.
The class looks like this:
class Foo(
id: Option[UUID],
obj: UUID,
lm: Date
)
I want to give the query a list of UUIDs which match the obj
property but only the latest according to lm
property.
The result of that query should be mapped to a list of class Bar
which looks like this:
class Bar(
obj: UUID,
ts: Date
)
The query looks like this (assuming col
is a JSONCollection
of the entity Foo
and ids
is a list of UUIDs.
import col.BatchCommands.AggregationFramework._
col
.aggregate(
Match(Json.obj("obj" -> Json.obj("$in" -> ids.map(_.toString)))),
List(
Sort(Descending("lm")),
Group(JsString("$obj"))("obj" -> FirstField("obj"), "ts" -> FirstField("lm")),
Project(Json.obj("_id" -> 0, "obj" -> "$obj", "ts" -> "$ts"))
)
)
.map(_.head[Bar])
This worked as expected until the upgrade to 0.13.0. To be more precise I use the reactivemongo play plugin 0.13.0-play26
The error now looks like this:
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[DefaultJSONCommandError: CommandError[code=<unknown>, errmsg=<unknown>, doc: {"obj":"a797ec90-80d7-4b5e-b144-2454436f2b16","ts":1526390247074}]]]
Unfortunately, I could not find documentation on the reactivemongo website, it seems the docs have not been updated since 0.11.x
Using the mongo cli the query looks like this:
db.Foo.aggregate([{ $match: { obj: { $in: ["<uuid>", "<uuid>"] } } },{ $sort: { lm: -1 } },{ $group: { _id: "$obj", ts: { $first: "$ts" } } }]);
and it gives me the correct result.
Can someone give me a hint, what I'm doing wrong here?
Upvotes: 2
Views: 371
Reputation: 932
use col.aggregatorContext
instead of col.aggregate
col
.aggregatorContext[Bar](
Match(Json.obj("obj" -> Json.obj("$in" -> ids.map(_.toString)))),
List(
Sort(Descending("lm")),
Group(JsString("$obj"))("obj" -> FirstField("obj"), "ts" -> FirstField("lm")),
Project(Json.obj("_id" -> 0, "obj" -> "$obj", "ts" -> "$ts"))
)
)
.prepared
.cursor
.collect[List](-1, reactivemongo.api.Cursor.FailOnError[List[Bar]]())
Upvotes: 2