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.
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:
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.
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)
}
)