Reputation: 107
I have a collection of versioned documents ("rHistory"), with this structure:
{
"rid": "123e",
"v": 1
},
{
"rid": "143fe",
"v": 1
},
{
"rid": "143fe",
"v": 2
},
{
"rid": "143fe",
"v": 3
},
{
"rid": "123e",
"v": 2
}
I'm writing a function to return a subset of the documents in this collection. Currently I find all matching items as follows:
_rHistory.Find(r => rIds.Contains(r.RId)).ToList()
However, I only want to return the highest versioned item of each result, like so:
{
"rid": "143fe",
"v": 3
},
{
"rid": "123e",
"v": 2
}
How can I find the newest version of each document matching a filter on rid and return the result as a list? I'm assuming aggregation is involved but I'm having trouble finding relevant examples. Obviously I'd rather not do this:
foreach (var rId in rIds)
{
res.Add(_rHistory.Find(r => r.RId == rId).SortByDescending(f => f.Version).FirstOrDefault());
}
Upvotes: 1
Views: 183
Reputation: 49945
Assuming your model looks like this:
public class Model
{
public ObjectId Id { get; set; }
public string rid { get; set; }
public int v { get; set; }
}
You can group by rid
and return .Max()
v
:
var col = database.GetCollection<Model>("rHistory");
var q = col.Aggregate()
.Group(
x => x.rid,
gr => new {rid = gr.Key, v = gr.Max(f => f.v)});
var result = q.ToList();
MongoDB .NET driver will translate such query into:
{ "$group" : { "_id" : "$rid", "v" : { "$max" : "$v" } }
Upvotes: 1