Merge pull request #7038 from strapi/rbac/filter-doc

Add _where parameter OR and AND doc v1
This commit is contained in:
Alexandre BODIN 2020-07-16 19:10:47 +02:00 committed by GitHub
commit 012d07cd97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

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