Sort search results by more than one field?

Is it possible to sort search results by more than one field? I’m pretty sure the answer to this is “no,” but I just want to confirm. I can workaround by sorting on the client side, but it would be easier if I could just do it in one step.

Per the docs:

To sort user search results, pass a field:order value to the sort parameter when making your request. The field is the name of the field to sort by, while order can be set to 1 for ascending order and -1 for descending.

I tried several different syntax combinations in the API explorer, such as:

email:1,name:-1
email:1|name:-1
email:1;name:-1
email:1 name:-1
email:1name:-1

All of them returned a 400: invalid_query_string result. (Note: I also sorted my search result by each of these two fields individually to make sure that they each worked on their own. No problems there.)

Like I said, I’m pretty sure the current API doesn’t allow this, but I just want to make sure there isn’t some super secret, undocumented, multi-field sort syntax that I’m unaware of. :wink:

Thanks!

For anyone who arrives on this page looking for a solution for how to sort Auth0 query results by more than one field, and you happen to be coding in JavaScript, here’s the solution I came up with. This was designed to convert a sort specification object that conforms to the FeathersJS Common API $sort property syntax.

/**
 * External packages upon which this implementation relies:
 *  * {@link https://www.npmjs.com/package/fast-sort|fast-sort}
 *  * {@link https://www.npmjs.com/package/lodash.get|lodash.get}
 *
 * @module helpers/sort
 */
const fs = require('fast-sort')
const get = require('lodash.get')

/**
 * Converts the sort specification object into the format required
 * by `fast-sort`. For more info, see the docs linked to above. It
 * assumes the `props` object conforms to the FeathersJS common API
 * {@link https://crow.docs.feathersjs.com/api/databases/querying.html#sort|$sort syntax}.
 *
 * @param   {object}   props An object containing sort keys as described below
 * @returns {object[]}       An array of objects of the format { asc|desc: keyname }
 */
const convertProps = props => Object.entries(props).map(
  ([key, order]) => {
    const k = key.includes('.') ? o => get(o, key) : key
    return order === 1 ? { asc: k } : { desc: k }
  }
)

/**
 * Defines a sort function that will sort an array of JavaScript
 * objects by multiple keys. The keys to sort by are specified in
 * an object of the following shape, where 1 === ascending order
 * and -1 === descending order. The order of the keys determines
 * their precedence in the resulting sorted array of objects.
 *
 * {
 *   key1: 1,
 *   key2: -1
 * }
 *
 * Internally it uses the npm `fast-sort` library.
 * It also uses `lodash.get` to create nested property accessors.
 * It will not mutate the input collection.
 *
 * @param   {object[]} collection The array of objects to be sorted
 * @param   {object}   props      The properties on which to sort
 * @returns {object[]}            A sorted copy of the input array
 */
const sort = (collection, props) => fs([...collection]).by(convertProps(props))

module.exports = { sort }

And then in the place where you actually query the Auth0 API (assumes you are using the node-auth0 library:

const { sort } = require('./helpers/sort') // sort helper defined above
const auth0 = require('auth0').ManagementClient
const client = new auth0({ domain, clientId, clientSecret }) // you must provide your own credentials ;)

// example of sorting Auth0 users first by which provider is primarily associated
// with their account (ascending), and then in descending order of `logins_count`.
// Yes, it can sort based on array elements, but it would be a good idea to be sure
// that those elements exist ahead of time. I haven't tested what happens if they don't...
const sortSpec = {
  "identities[0].provider": 1,
  "logins_count": -1
}

// perform the query; gets the max allowable number of record (100)
client.getUsers({ per_page: 100 }).then(
  users => {
    const sorted = sort(users, sortSpec) 
    // do something with your sorted result
    console.log(sorted)
  }
)

Hope this helps someone! Good luck!!

1 Like

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.