This is sample data (expireDate is optional):
{"userId":"1","appId":"1","createdDate":10}
{"userId":"1","appId":"1","createdDate":5,"expireDate":30}
{"userId":"1","appId":"1","createdDate":12,"expireDate":20}
{"userId":"1","appId":"1","createdDate":12,"expireDate":5}
This is the aggregation function that I want to translate to reactivemongo aggregation framework:
db.collection_name.aggregate([
{
$match : {"userId" : "1"}
},
{
$group : {
"_id" : "$appId",
"docs" : {
$max : {
"createdDate" : "$createdDate",
"expireDate" : "$expireDate"
}
}
}
}
])
To run the aggregation function on the sample data (with mongo shell 3.2.9), the result is:
{ "_id" : "1", "docs" : { "createdDate" : 12, "expireDate" : 20 } }
When I try to convert this aggregation function to reactivemongo, I realize that the group function "Max" only takes one string as parameter, so I don't know how to put both "createdDate" and "expireDate" in it. Here is what I figure out so far:
col.aggregate(
Match(BSONDocument("userId" -> "1")),
List(Group(BSONString("$appId"))( "docs" -> Max("createdDate")))
)
Can anybody tell me how to add "expireDate" into "Max" function?
Note that I'm using reactivemongo 0.11, and upgrading to 0.12 is not an option.
You can use reactivemongo.api.commands.AggregationFramework.GroupFunction.apply
to create a custom call to a group function. Here is the doc and here is the source where I found it.
GroupFunction("$max", BSONDocument("createdDate" -> "$createdDate", "expireDate" -> "$expireDate"))
Use this function instead of Max
, so your code becomes:
col.aggregate(
Match(BSONDocument("userId" -> "1")),
List(Group(BSONString("$appId"))( "docs" -> GroupFunction("$max", BSONDocument("createdDate" -> "$createdDate", "expireDate" -> "$expireDate"))))
)
Don't forget to import col.BatchCommands.AggregationFramework.GroupFunction
.
Of course you can define a more generic function which takes any BSONDocument
as a parameter, if you want:
def BetterMax(doc: BSONDocument) = GroupFunction("$max", doc)