Skip to content

Commit 66ab0c7

Browse files
Deckstarbenjie
andauthored
Update make-add-pg-table-order-by-plugin.md (#275)
Co-authored-by: Benjie Gillam <benjie@jemjie.com>
1 parent 52ed92e commit 66ab0c7

1 file changed

Lines changed: 44 additions & 2 deletions

File tree

src/pages/postgraphile/make-add-pg-table-order-by-plugin.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ reversed sort:
136136
export function orderByAscDesc(
137137
baseName: string,
138138
columnOrSqlFragment: string | SQL,
139-
unique = false
139+
uniqueOrOptions: boolean | OrderByAscDescOptions = false
140140
): MakeAddPgTableOrderByPluginOrders;
141141
```
142142

@@ -146,4 +146,46 @@ this function creates.
146146
`columnOrSqlFragment` is where the order value is specified, it becomes the
147147
first entry in the `OrderSpec` tuple defined above.
148148

149-
Only set `unique` to true if you can guarantee that the sort order is unique.
149+
`uniqueOrOptions` define 1) whether the sort order is unique, and 2) how to sort null values when sorting by ascending and descending order. Only set `uniqueOrOptions` (or `unique`) to `true` if you can guarantee that the sort order is unique.
150+
151+
As of v4.12, you can also customize how nulls are sorted:
152+
153+
```ts
154+
export type NullsSortMethod =
155+
| "first"
156+
| "last"
157+
| "first-iff-ascending"
158+
| "last-iff-ascending"
159+
| undefined;
160+
161+
export interface OrderByAscDescOptions {
162+
unique?: boolean;
163+
nulls?: NullsSortMethod;
164+
}
165+
```
166+
The `nulls` option extends the `ORDER BY` clause of the SQL query with either `NULLS FIRST` or `NULLS LAST` according to the following rules:
167+
- "first": specify `NULLS FIRST` for both ascending and descending;
168+
- "last": specify `NULLS LAST` for both ascending and descending;
169+
- "first-iff-ascending": specify `NULLS FIRST` when ordering by ascending, and `NULLS LAST` when ordering by descending;
170+
- "last-iff-ascending": specify `NULLS LAST` when ordering by ascending, and `NULLS FIRST` when ordering by descending;
171+
- (default) undefined: omit both `NULLS FIRST` and `NULLS LAST` in the order by clause for both ascending and descending, thus using the default ordering behavior.
172+
173+
For example, you may wish to create a plugin to sort movies by either top-rated or lowest-rated first (meaning the average of the movie's reviews):
174+
```ts
175+
const customOrderBy = orderByAscDesc(
176+
'RATING',
177+
(helpers) => {
178+
const { queryBuilder } = helpers;
179+
180+
const orderByFrag = sql.fragment`(
181+
select avg(${sqlIdentifier}.rating)
182+
from app_public.movie_reviews as ${sqlIdentifier}
183+
where ${sqlIdentifier}.movie_id = ${queryBuilder.getTableAlias()}.id
184+
)`;
185+
186+
return orderByFrag;
187+
},
188+
{ nulls: 'last' },
189+
);
190+
```
191+
To get the top-rated movies, one would then use the `RATING_DESC` option in the GraphQL query. However, by default, `RATING_DESC` would put movies with no reviews (and thus an average of `null`) first, followed by the sorted movies. A movie with no ratings is not exactly what one thinks of when one hears "top-rated"! By specifying `{ nulls: 'last' }`, however, PostGraphile knows that this orderBy plugin should still show the movies without any reviews, but just put them at the end of the list.

0 commit comments

Comments
 (0)