Sorting with mongoose and mongoDB

I have a userModel that has about 5 fields that I would like to be sorted in Ascending or Descending when I find({}) them. Everything I have read from the documentation suggests that this should work but it’s not working.

This query only returns a correct order for the first value e.g firstName and returns a non-sorted result for the rest. These are the different sorting techniques that I’ve tried to implement and all return the same result. if I try to flip to Descending order, the exact same behaviour occurs.

UserModel.find({}).sort({firstName: 'asc', lastName:'asc' ,email:'asc',createdAt:'asc', updatedAt:'asc' })
UserModel.find({}).sort({firstName: 1, lastName:1 ,email:1, createdAt:1 , updatedAt: 1 })
UserModel.find({}).sort("firstName lastName email createdAt updatedAt")
UserModel.find({}).sort("firstName, lastName, email, createdAt, updatedAt")

I Also tried to create an index before sorting but still, only the first field is getting sorted

const UserSchema = new mongoose.Schema(
  {
    firstName: {
      type: String,
      required: [true, "Please enter a valid first name."],
    },
    lastName: {
      type: String,
      required: [true, "Please enter a valid last name."],
    },
    email: {
      type: String,
      required: [true, "Please provide a valid email address."],
      unique: true
    },
    createdAt: {
      type: Date,
      default: null,
    },
    updatedAt: {
      type: Date,
      default: null,
    },
)

UserSchema.index({firstName: 1, lastName:1 ,email:1, createdAt:1 , updatedAt: 1 }) 

export default mongoose.models.User || mongoose.model("User", UserSchema)

What am i doing wrongly?

1 Like

Hello @muhammed_ogunsanya, welcome to the community
sort() takes an object as parameter where the values are 1 or -1
Use -1 for descending order and 1 for ascending
same idea goes for index creation
eg:

sort({firstName: 1, lastName:-1 ,email:1,createdAt:1, updatedAt:1 })
sort({firstName: -1, lastName:-1 ,email:1,createdAt:1, updatedAt:1 })

if you want to reverse the order use

sort({firstName: -1, lastName:-1 ,email:-1,createdAt:-1, updatedAt:-1 })

the last sort is covered by the index (in backward), while the first two will do an in memory sort

Hope that was informative, take care

1 Like

Hello @Imad_Bouteraa unfortunately i’ve tried doing this. if you check the code i posted you’d see that i’ve tried these methods. im just confused as to why its not working

1 Like

please double check your post, there is no -1

1 Like

In this case i am only trying to sort in ascending order. if i change the 1 to -1, still only the first field(firstName) ends up being sorting in descending order. i resolves for the first field and ignores the rest(lastname, email etc)

1 Like

have you tried this exact sort?

if you still don’t get the expected behavior, please share a sample of your data

1 Like

same behavior. please what do you need me to share? Thank you

1 Like

@Imad_Bouteraa what data do you need please

1 Like

I’m back,
please share just three or four documents and what are you expecting as result of the query

1 Like

Okay will do that now

1 Like

Have you taken a look at my schema? @Imad_Bouteraa

2 Likes
    {
      "_id": { "$oid": "notarealid" },
      "emailVerified": false,
      "dob": null,
      "createdAt": { "$date": "2021-06-16T10:03:46.820Z" },
      "authId": "test",
      "firstName": "Hello",
      "lastName": "world",
      "email": "abbbbb@zamox.com",
      "sourceSite": "dev",
      "products": []
    }

    {
      "_id": { "$oid": "notarealid" },
      "emailVerified": false,
      "dob": null,
      "createdAt": { "$date": "2021-06-16T10:03:46.820Z" },
      "authId": "test",
      "firstName": "Lois",
      "lastName": "Lane",
      "email": "bbbbb@zamox.com",
      "sourceSite": "dev",
      "products": []
    }

    {
      "_id": { "$oid": "notarealid" },
      "emailVerified": false,
      "dob": null,
      "createdAt": { "$date": "2021-06-16T10:03:46.820Z" },
      "authId": "test",
      "firstName": "Clark",
      "lastName": "Kent",
      "email": "cbbbbb@zamox.com",
      "sourceSite": "dev",
      "products": []
    }

    {
      "_id": { "$oid": "notarealid" },
      "emailVerified": false,
      "dob": null,
      "createdAt": { "$date": "2021-06-16T10:03:46.820Z" },
      "authId": "test",
      "firstName": "Lex",
      "lastName": "Luthor",
      "email": "dbbbbb@zamox.com",
      "sourceSite": "dev",
      "products": []
    }

i changed the values because of company policy. but what i’m expecting is when i try to sort by any field, i should get them either by asc or desc depending on which i specify. but it on returns the correct other for whichever field i pass in the first position. e.g sort({firstName: -1, lastName:-1 ,email:-1,createdAt:-1, updatedAt:-1 }) wlll return in descending order for firstName alone

1 Like

Your example does not show the case of sorting with multiple fields
sort({firstName: -1, lastName:-1 ,email:-1,createdAt:-1, updatedAt:-1 }) means that mongodb will sort in descending order according to the firstName. if two documents have the same firstName mongodb will check there lastName
example:
given the following documents

{firstName:"za",lastName:"aa"}
{firstName:"za",lastName:"zz"}
{firstName:"zz",lastName:"aa"}

when sorted by

sort({firstName: -1, lastName:-1})

you get

{firstName:"zz",lastName:"aa"}
{firstName:"za",lastName:"zz"}
{firstName:"za",lastName:"aa"}

note that lastName is used only when the two documents have the same firstName

2 Likes

I am a little confused. are you saying that sort({firstName: -1, lastName:-1 ,email:-1,createdAt:-1, updatedAt:-1 }) does not represent trying to sort by multiple fields?

1 Like
function getAscUsers(){
return UserModel.find().sort({
    firstName: -1,
    email: -1,
  })
}

This is a replica of what my query looks like. after this i make a query in my grapql resolver

  getOrderedUsersAsc {
     email
  }
1 Like

I said

If all the documents have distinct first names, mongodb will sort them by the first name

2 Likes

Hi @muhammed_ogunsanya,

It would be very helpful if you can provide the query you are using, current output, and expected output for your four sample documents.

I also recommend working out your query order using a MongoDB query before testing via GraphQL (which could also affect the order of results).

Thanks,
Stennie

1 Like

Hello im back i was prohibited from sending out any more replies yesterday.

1 Like

@Imad_Bouteraa @Stennie_X Mongo playground i have taken out the time to recreate the issue on the playground. i finally understood @Imad_Bouteraa comment and i can now see that i am going about it the wrong way. the documents i get back are in order of the first sorting field and cannot be altered. my question is, is there a way to sort by multiple fields in the same query? in this case, if i get the lastName in asc order, can i also get the email in asc order simultaneously. i hope someone understands my question

2 Likes

@Stennie_X @Imad_Bouteraa please check the attached mongoplayground link

1 Like