Search code examples
c#mongodbmongodb-.net-drivermongodb-csharp-2.0

C# mongodb 2.0 Find and project ordered part of an array


I have the following codeblock:

var r = this.collections.competitions.Find(filter)
                                             .Project(x => x.TeamRanks)
                                             .Project(t => t.Logo)
                                             .Sort(sort)
                                             .Skip(prev)
                                             .Limit(count)
                                             .Single();

I have this Competition collection which have 3 fields

Class Competition {
           public ObjectId _Id;
           public string Logo;
           public List<string> TeamRanks
}

The filter here is on the Competition._Id. I want to get the Logo AND the first 5 ranked teams in a Rank ascending order.(Which are given by the count value) The list might be huge so I want to use Project here (or an alternative solution with Fields) but it can't seem to work. issues:

1. r is of type string which is the second Project and ignoring the TeamRanks.

2. How can I only get the top 5 ranked teams in an ascending order?

TIA.

EDIT

I just now noticed that the entire sort, skip and limit are done on the competition, I want it to be applied on the TeamRanks of course. So if, for example, the method receives count = 7 and some competitionId, the method need to return the competition with the provided id and inside it the top 7 teams ordered..


Solution

  • ObjectId _idFilter = new ObjectId();//you set your _Id filter to whatever you need
    Competition _theCompetition = await __db.GetCollection<Competition>("Competiton")
        .Find(Builders<Competition>.Filter.Eq("_Id", _idFilter)).SingleAsync();
    int _count = 5; //your chosen count
    List<string> _orderedList = _theCompetition.TeamRanks
        .OrderBy(teamRank => teamRank).Take(_count).ToList();
    

    EDIT
    Below is the code that gets the first five elements of the TeamRanks array in the returned document

    var __projection = Builders<Competition>.Projection;
    var _theCompetition = await __db.GetCollection<Competition>("Competiton")
    .Find(Builders<Competition>.Filter.Eq("_id", _idFilter))                  
    .Project(__projection.Include(x=>x.Logo).Include(x=>x.TeamRanks).Slice("TeamRanks", 5))
    .SingleAsync();