essi
essi

Reputation: 107

How can I get a subset of results in MongoDB C# Driver?

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

Answers (1)

mickl
mickl

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

Related Questions