0

I need to sort a list on multiple values. Data comes from a MongoDb database and I load its from C#.

SAMPLE

Unsorted            
OwnerId     Status      Date
123         New         2016-01-01
456         New         2016-01-01
789         New         2016-01-06
123         New         2016-01-05
456         Qualified   2016-01-05
789         Converted   2016-01-01
123         Qualified   2016-01-02

Expected
OwnerId     Status      Date
123         New         2016-01-05
123         New         2016-01-01
123         Qualified   2016-01-02
789         New         2016-01-06
456         New         2016-01-01
456         Qualified   2016-01-05
789         Converted   2016-01-01

I need to show OwnerId 456 first, then New status first, then Date descending.

OwnerId is a dynamic value : it's my current authenticated user in my app. I can't access this value from anywhere. OwnerId value type is a GUID in real case.

I try this without success : c# How to sort a sorted list by its value column1

C# List<> Sort by x then y2

I hope my problem is enough understandable. Do not hesitate to ask more details. Thanks in advance.

Edited :

I can't achieve this with mongo directly. I need a C# solution.

Community
  • 1
  • 1
Karine
  • 491
  • 1
  • 4
  • 18
  • You want the answer with mongo query? As you have tagged `mongodb` in your question I am asking. Also the questions you have given link of, are not related to mongo query. – Shrabanee Jul 22 '16 at 09:06
  • either with Mongo or C# – Karine Jul 22 '16 at 09:21
  • Using mongodb` one query can help you, but it will apply the same sorting` on `ownerId - 456 and 789` as well. Is it okay to get the result that way`?` – Shrabanee Jul 22 '16 at 09:24
  • Yes it's okay if it apply same sorting on all ownerId – Karine Jul 22 '16 at 10:04
  • *"I try this without success"* - why without success? Did the computer blow up? – Default Jul 22 '16 at 13:13
  • 1
    Possible duplicate of [How to specify an Order or Sort using the C# driver for MongoDB?](http://stackoverflow.com/questions/2123529/how-to-specify-an-order-or-sort-using-the-c-sharp-driver-for-mongodb) – Default Jul 22 '16 at 13:17
  • Possible duplicate of [How to use orderby with 2 fields in linq?](http://stackoverflow.com/questions/1989674/how-to-use-orderby-with-2-fields-in-linq) – Kira Jul 23 '16 at 05:34
  • possible duplicate of http://stackoverflow.com/questions/298725/multiple-order-by-in-linq – Kira Jul 23 '16 at 05:35
  • It's not a duplicate post. I need to sort according a dynamic value : the Id of my current authenticated user. It can be 123 or 456 or 789. Your links just make a sort like `123,456,789`. It's not what I expect. If my current user is 456, I want to show 456 first. If he is 789, I want to show 789 first. – Karine Jul 25 '16 at 07:59
  • 1
    @Karine I am thinking the easiest way would be two different queries? I currently cannot think of a cleaner way in C# to do what you want, so you might end up doing better with two queries, i.e. you don't seem to want to just sort by "Owner ID->New->Date Desc", you want to do "Owner ID 456 ->New -> Date Desc" + "Owner ID !456 -> !456 New-> !456 Date Desc". If nobody has another answer, consider two queries and removing the intersections – Tyress Jul 26 '16 at 00:20

4 Answers4

0

You can sort using this query:

db.<people>.sort( { OwnerId : 0, Date : 1 })

Do you need to translate this query in C# using MongoDB client?

Igor Damiani
  • 1,682
  • 6
  • 12
  • This query is not enough to give the desired output in the question. Please read and understand question before giving answer. – Shrabanee Jul 22 '16 at 09:32
  • LOL. Maybe here you can find a solution http://stackoverflow.com/questions/2123529/how-to-specify-an-order-or-sort-using-the-c-sharp-driver-for-mongodb – Igor Damiani Jul 22 '16 at 09:40
  • Will it sort `status` field as well? That is what is missing in your query I think. – Shrabanee Jul 22 '16 at 09:59
  • Yes I need to translate it in C#. I use MongoDb C# driver – Karine Jul 22 '16 at 10:05
0

Try this query which may help you getting your desired result:-

db.collName.find({findQuery}).sort({ 'OwnerId' : 1, 'Status':1, 'Date' : -1 })

The query will first sort your records in ascending order for OwnerId. Then it will sort based on value of status and in the end it will sort in descending order for Date field.

Now you should get your desired result with all the sorting

See sort-example for more idea on how you can use it in various ways. See the last example which is similar to your requirement.

Hope this will help you.

NOTE :- If there are lots of records, use .limit() as well with your query. See doc.

Shrabanee
  • 2,506
  • 1
  • 16
  • 26
  • I don't want ascending sort. I want sort based on a value. It will not work if my current user is OwnerId 456. And the status will be sort like this 'Converted, New, Qualified' but I want 'New' in first – Karine Jul 22 '16 at 11:03
  • Ok! Then mongo query can not help you seems. You have to do it manually only. I can't help you as I have no idea on `C#`. – Shrabanee Jul 22 '16 at 11:07
  • 1
    Ok, thanks for the lead. I know now I can't achieve this with mongo – Karine Jul 22 '16 at 12:23
0

I copied your data set, but your projected sort outcome is a little off specifically the OwnerId property. However, run this code inside of a Console application (or whatever template you prefer), and let me know if these are the results you are seeking:

public class GonnaSortThisData
{
    public GonnaSortThisData()
    {
        User currentUser = new User
        {
            UserId = 123,
            UserName = "UserMan"
        };

        List<Data> dataValues = new List<Data>
        {
            new Data {OwnerId = 123, Status = Status.New, Date = DateTime.Parse(@"2016-01-01")},
            new Data {OwnerId = 456, Status = Status.New, Date = DateTime.Parse(@"2016-01-01")},
            new Data {OwnerId = 789, Status = Status.New, Date = DateTime.Parse(@"2016-01-06")},
            new Data {OwnerId = 123, Status = Status.New, Date = DateTime.Parse(@"2016-01-05")},
            new Data {OwnerId = 456, Status = Status.Qualified, Date = DateTime.Parse(@"2016-01-05")},
            new Data {OwnerId = 789, Status = Status.Converted, Date = DateTime.Parse(@"2016-01-01")},
            new Data {OwnerId = 123, Status = Status.Qualified, Date = DateTime.Parse(@"2016-01-02")}
        };

        //var = List<Data>
        var sortedValues = dataValues
            .OrderByDescending(list => list.OwnerId == currentUser.UserId)
            .ThenBy(list => list.Status)
            .ThenByDescending(list => list.Date).ToList();
    }
}

public class User
{
    public int UserId { get; set; }
    public string UserName { get; set; }
}

public class Data
{
    public dynamic OwnerId { get; set; }
    public Status Status { get; set; }
    public DateTime Date { get; set; }
}

public enum Status
{
    New, Qualified, Converted
}

Please ignore the Enum and Data class as they were merely to represent the records that stem from the MongoDB database table. The dynamic property will be resolved by LINQ on the fly at runtime. Look carefully at the calls to ThenBy(). This is one of my most favorite LINQ extensions, and please note you have the ability to do this in query syntax, but I simply chose to use method syntax.

BolletuH
  • 124
  • 4
  • I need to sort my OwnerId according to a dynamic value. It can be 456 or 123 or 789 to show first. Your solution will sort 123,456,789. It's not what I expect – Karine Jul 25 '16 at 07:55
  • 1
    I'm sorry I misread your question slightly, I thought you meant the type was literally dynamic for OwnerId, not that the value will change during runtime. I have an issue with this comment however, "OwnerId is a dynamic value : it's my current authenticated user in my app. I can't access this value from anywhere. OwnerId value type is a GUID in real case." I'm not sure how you think we can manipulate our query if we are unable to access the property. I suppose we need to see the domain model of these types before proceeding. – BolletuH Jul 25 '16 at 23:56
0

Example of multiple sort

  return await Collection()
       .Find(_ => true)
       .Sort(Builders<SomeEntity>.Sort.Descending(x => x.SomeValueToSort1).Descending(x => x.SomeValueToSort2))
       .ToListAsync();