# Parameters See the [parameters' concepts](../concepts/concepts.md#parameters) for details. ::: note By default, the filters can only be used from `find` endpoints generated by the Content Type Builder and the [CLI](../cli/CLI.md). If you need to implement a filters system somewhere else, read the [programmatic usage](#programmatic-usage) section. ::: ## Available operators The available operators are separated in four different categories: - [Filters](#filters) - [Sort](#sort) - [Limit](#limit) - [Start](#start) ### Filters Filters are used as a suffix of a field name: - Not suffix or `eq`: Equals - `ne`: Not equals - `lt`: Lower than - `gt`: Greater than - `lte`: Lower than or equal to - `gte`: Greater than or equal to - `in`: Included in an array of values - `nin`: Isn't included in an array of values - `contains`: Contains - `ncontains`: Doesn't contain - `containss`: Contains case sensitive - `ncontainss`: Doesn't contain case sensitive - `null`: Is null/Is not null #### Examples ##### Find users having `John` as first name. `GET /users?firstName=John` or `GET /users?firstName_eq=John` ##### Find products having a price equal or greater than `3`. `GET /products?price_gte=3` ##### Find multiple product with id 3, 6, 8 `GET /products?id_in=3&id_in=6&id_in=8` ##### Or clauses If you use the same operator (except for in and nin) the values will be used to build an `OR` query `GET /posts?title_contains=article&title_contains=truc` ### Deep filtering Find posts written by a user who belongs to a company with the name equal to Strapi `GET /posts?author.company.name=strapi` ::: warning Querying your API with deep filters may cause performance issues. If one of your deep filtering queries is too slow, we recommend building a custom route with an optimized version of your query. ::: ::: note This feature doesn't allow you to filter nested models, e.g `Find users and only return their posts older than yesterday`. To achieve this, there are two options: - Either build a custom route or modify your services - Use [GraphQL](./graphql.md#query-api) ::: ::: warning This feature isn't available for the `upload` plugin. ::: ### Sort Sort according to a specific field. #### Example Sort users by email. - ASC: `GET /users?_sort=email:ASC` - DESC: `GET /users?_sort=email:DESC` Sorting on multiple fileds - `GET /users?_sort=email:asc,dateField:desc` - `GET /users?_sort=email:DESC,username:ASC` ### Limit Limit the size of the returned results. #### Example Limit the result length to 30. `GET /users?_limit=30` You can require the full data set by passing a limit equal to `-1` ### Start Skip a specific number of entries (especially useful for pagination). #### Example Get the second page of results. `GET /users?_start=10&_limit=10` ## Programmatic usage You can use `strapi-utils` to parse the query params to Strapi's standards filters programmatically if you need it. ### Extracting requests filters To transform the query params to Strapi's standard filters a request, you can use the `convertRestQueryParams` function from [strapi-utils](../api-reference/reference.md#strapiutils). ```js const { convertRestQueryParams } = require('strapi-utils'); module.exports = { // when sending a request like GET /products?_sort:id&id=1 fetchExpensiveProducts: (params, populate) => { const filters = convertRestQueryParams(params); /** * filters = { * start: 0, * limit: 10, * sort: [{ field: 'id', order: 'desc' }], * where: [ * { field: 'id', operator: 'eq', value: 1 }, * ] * } */ // do sth with them }, }; ``` ### Querying data We added a new API to query data base on the new filters API. ```js const { convertRestQueryParams, buildQuery } = require('strapi-utils'); module.exports = { find: async (ctx) => { // Convert params. const filter = convertRestQueryParams(ctx.request.query); return buildQuery({ model: Article filters, populate: [] }); }; }; ``` #### SQL databases (strapi-hook-bookshelf) If you are using a SQL database, calling `buildQuery` will return a [`Bookshelf Query`](https://bookshelfjs.org/api.html) on which you can call other functions (e.g `count`) #### Mongo database If you are using a mongo database calling `buildQuery` returns either a [`Mongoose Query`](https://mongoosejs.com/docs/api.html#Query) or a custom query when used with deep filtering. ##### Custom Query When using the deep filtering feature with mongo, we build an aggregation query to avoid too many round-trips with the mongo DB. Doing that means we don't get a Mongoose object as a response but instead a plain JS Object. This brings a some issues like no virtual fields available and no Mongoose lifecycles. To deliver the best possible experience, we decided to rehydrate the Mongoose models, forcing us to override the Mongoose query ```js const query = buildQuery({ model: Product, // you can use any models from strapi.models or strapi.plugins[pluginName].models filters: { limit: 10 }, populate: [], }); ``` returns a query with the following functions - `count` => Returns an integer equal to the number of matching entities - `lean` => Returns the matching elements as Objects - `then(onSucces, onFailure)` => Calls the onSucces with an array of Mongoose objects. - `catch(onError)` => Promise catch - `group(options)` => Calls the aggregation group function of mongoose