diff --git a/docs/v3.x/content-api/parameters.md b/docs/v3.x/content-api/parameters.md index 68a6c4afbf..2870e5e8a1 100644 --- a/docs/v3.x/content-api/parameters.md +++ b/docs/v3.x/content-api/parameters.md @@ -20,6 +20,8 @@ The available operators are separated in four different categories: ## Filters +When using filters you can either pass simple filters in the root of the query parameters or pass them in a `_where` parameter. + Filters are used as a suffix of a field name: - No suffix or `eq`: Equals @@ -52,18 +54,137 @@ or `GET /restaurants?id_in=3&id_in=6&id_in=8` -#### Or clauses +#### Using `_where` -If you use the same operator (except for in and nin) the values will be used to build an `OR` query +`GET /restaurants?_where[price_gte]=3` -`GET /restaurants?name_contains=pizza&name_contains=giovanni` +`GET /restaurants?_where[0][price_gte]=3&[0][price_lte]=7` + +## Complexe queries + +When building more complexe queries you must use the `_where` query parameter in combination with the [`qs`](https://github.com/ljharb/qs) library. + +We are taking advantage of the capability of `qs` to parse nested objects to create more complexe queries. + +This will give you full power to create complexe queries with logical `AND` and `OR` operations. + +::: tip NOTE +We strongly recommend using `qs` directly to generate complexe queries instead of creating them manually. +::: + +### `AND` operator + +The filtering implicitly supports the `AND` operation when specifying an array of expressions in the filtering. + +**Examples** + +Restaurants that have 1 `stars` and a `pricing` less than or equal to 20: + +```js +const query = qs.stringify({ + _where: [{ stars: 1 }, { pricing_lte: 20 }], +}); + +await request(`/restaurants?${query}`); +// GET /restaurants?_where[0][stars]=1&_where[1][pricing_lte]=20 +``` + +Restaurants that have a `pricing` greater than or equal to 20 and a `pricing` less than or equal to 50: + +```js +const query = qs.stringify({ + _where: [{ pricing_gte: 20 }, { pricing_lte: 50 }], +}); + +await request(`/restaurants?${query}`); +// GET /restaurants?_where[0][pricing_gte]=20&_where[1][pricing_lte]=50 +``` + +### `OR` operator + +To use the `OR` operation, you will need to use the `_or` filter and specify an array of expressions on which to perform the operation. + +**Examples** + +Restaurants that have 1 `stars` OR a `pricing` greater than 30: + +```js +const query = qs.stringify({ _where: { _or: [{ stars: 1 }, { pricing_gt: 30 }] } }); + +await request(`/restaurant?${query}`); +// GET /restaurants?_where[_or][0][stars]=1&_where[_or][1][pricing_gt]=30 +``` + +Restaurants that have a `pricing` less than 10 OR greater than 30: + +```js +const query = qs.stringify({ _where: { _or: [{ pricing_lt: 10 }, { pricing_gt: 30 }] } }); + +await request(`/restaurant?${query}`); +// GET /restaurants?_where[_or][0][pricing_lt]=10&_where[_or][1][pricing_gt]=30 +``` + +### Implicit `OR` operator + +The query engine implicitly uses the `OR` operation when you pass an array of values in an expression. + +**Examples** + +Restaurants that have 1 or 2 `stars`: + +`GET /restaurants?stars=1&stars=2` + +or + +```js +const query = qs.stringify({ _where: { stars: [1, 2] } }); + +await request(`/restaurant?${query}`); +// GET /restaurants?_where[stars][0]=1&_where[stars][1]=2 +``` + +::: tip NOTE +When using the `in` and `nin` filters the array is not transformed into a OR. +::: + +### Combining AND and OR operators + +Restaurants that have (2 `stars` AND a `pricing` less than 80) OR (1 `stars` AND a `pricing` greater than or equal to 50) + +```js +const query = qs.stringify({ + _where: { + _or: [ + [{ stars: 2 }, { pricing_lt: 80 }], // implicit AND + [{ stars: 1 }, { pricing_gte: 50 }], // implicit AND + ], + }, +}); + +await request(`/restaurants?${query}`); +// GET /restaurants?_where[_or][0][0][stars]=2&_where[_or][0][1][pricing_lt]=80&_where[_or][1][0][stars]=1&_where[_or][1][1][pricing_gte]=50 +``` + +**This also works with deep filtering** + +Restaurants that have (2 `stars` AND a `pricing` less than 80) OR (1 `stars` AND serves French food) + +```js +const query = qs.stringify({ + _where: { + _or: [ + [{ stars: 2 }, { pricing_lt: 80 }], // implicit AND + [{ stars: 1 }, { 'categories.name': 'French' }], // implicit AND + ], + }, +}); + +await request(`/restaurants?${query}`); +// GET /restaurants?_where[_or][0][0][stars]=2&_where[_or][0][1][pricing_lt]=80&_where[_or][1][0][stars]=1&_where[_or][1][1][categories.name]=French +``` ::: warning - -If you want to use `AND` for your query you will have to create a custom query by using the [Query](../concepts/queries.md) documentation. - -Strapi doesn't support the `AND` operator for now. - +When creating nested queries, make sure the depth is less than 20 or the query string parsing will fail for now. ::: ## Deep filtering