jmcd
jmcd

Reputation: 4300

How to specify an Order or Sort using the C# driver for MongoDB?

I'm trying to figure out how to sort a collection of documents server side by telling the C# driver what the sort order is, but it appears not to support that construct yet.

Is it possible to do this any other way?

Upvotes: 67

Views: 102303

Answers (11)

Kaveh Naseri
Kaveh Naseri

Reputation: 1266

You can apply sort with SortDefinition like this:

FilterDefinition<User> filter = Builders<User>.Filter.Eq(a => a.Deleted , false);
SortDefinition<User> sort = Builders<User>.Sort.Descending(a => a.Id);
List<User> result = _dbContext.Users.Find(filter).Sort(sort).Limit(10).ToList();

Upvotes: 11

Mike
Mike

Reputation: 937

I'm currently using the API version MongoDB.Driver 2.8.1. Here is my method that I call to return a list of objects with Descending sorting, if it is required:

public static IEnumerable<TEntity> GetDocumentsForCollection(
        IMongoDatabase database,
        string collectionName,
        FilterDefinition<TEntity> query,
        string databaseCollectionKeyToSortOnDescending)
    {
        var _mongoSettings = new MongoCollectionSettings();
        _mongoSettings.GuidRepresentation = GuidRepresentation.Standard;
        var _collection = database.GetCollection<TEntity>(collectionName, _mongoSettings);

        if (string.IsNullOrEmpty(databaseCollectionKeyToSortOnDescending))
        {
            return _collection.Find(query).ToList();
        }

        return _collection.Find<TEntity>(query).Sort(Builders<TEntity>.Sort.Descending(databaseCollectionKeyToSortOnDescending)).ToList();
    }

Upvotes: 2

Jack
Jack

Reputation: 3057

@DmitryZyr's answer for FindAsync was not working. This one did however.

var sortDefinition = new SortDefinitionBuilder<ImmutableLog>().Descending("date");
var findOptions = new FindOptions<ImmutableLog>() {Sort = sortDefinition};
await this.Collection.FindAsync(new BsonDocument(), findOptions);

Upvotes: 3

Mohammad Akbari
Mohammad Akbari

Reputation: 4766

Simple usage of api in MongoDB.Driver 2.5.0

var client = new MongoClient("mongodb://localhost:27017");

var database = client.GetDatabase("Blog");

var list = database.GetCollection<BlogPost>("BlogPost")
    .Find(e => e.Deleted == false)
    .SortByDescending(e => e.CreatedOn)
    .Limit(20)
    .ToList();

Upvotes: 30

Dmitrii Zyrianov
Dmitrii Zyrianov

Reputation: 2318

For async methods:

var filter = Builders<BsonDocument>.Filter.Empty;
var sort = Builders<BsonDocument>.Sort.Ascending("time");
collection.FindAsync(filter, new FindOptions<BsonDocument, BsonDocument>()
{
    Sort = sort
});

Upvotes: 44

Sergej Popov
Sergej Popov

Reputation: 3021

Just to add to Chris's answer, in C# Driver 2.x it is now done with SortBy, SortByDescending, ThenBy & ThenByDescending

collection.Find(bson => true).SortBy(bson => bson["SortByMeAscending"]).ThenByDescending(bson => bson["ThenByMeDescending"]).ToListAsync()

Now it resembles Linq even more.

http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/crud/reading/#sort

Upvotes: 38

Shy Peleg
Shy Peleg

Reputation: 645

If you want to use linq:

From the documentation: (http://docs.mongodb.org/ecosystem/tutorial/use-linq-queries-with-csharp-driver/)

var query=
    (from c in collection.AsQueryable<C>()
    orderby c.X
    select c)

foreach (var d in query)
{
    // process your documents
}

If you want you can also limit the results:

var query=
    (from c in collection.AsQueryable<C>()
    orderby c.X descending
    select c).Take(1);

Just remember to have an index on the field you are sorting by : ]

Upvotes: 9

Darius
Darius

Reputation: 1149

Note that to sort on multiple fields use this:

db["collection"].Find().SetSortOrder(SortBy.Ascending("SortByMe").Descending("An‌​dByMe");

Upvotes: 10

Chris Brook
Chris Brook

Reputation: 2543

You can also do it using the SetSortOrder method on the MongoCursor class:

db["collection"].Find().SetSortOrder(SortBy.Ascending("SortByMe"));

Upvotes: 86

jmcd
jmcd

Reputation: 4300

It seems the way to do this using the existing C# driver is as follows:

db["collection"].Find(new Document().Append("query", 
new Document()).Append("orderby", 
new Document().Append(name:1).Append(age,-1))); 

Which I was turned on to by Sam Corder here

Upvotes: 6

kris
kris

Reputation: 23592

I'm doing this in JavaScript since I don't know C#, but it should have equivalent syntax with the C# driver.

If your query looked like:

db.c.find({"foo" : "bar"})

and you want to sort by "baz" ascending, wrap your query in a "query" field and add an "orderby" field:

db.c.find({"query" : {"foo" : "bar"}, "orderby" : {"baz" : 1}})

For descending sort, use -1.

Upvotes: -2

Related Questions