Auth0 Home Blog Docs

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!!

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