mirror of
https://github.com/ent/ent.git
synced 2026-04-28 05:30:56 +03:00
dialect/sql/sqljson: support for order by value and length (#3278)
This commit is contained in:
@@ -1,69 +0,0 @@
|
||||
---
|
||||
id: paging
|
||||
title: Paging And Ordering
|
||||
---
|
||||
|
||||
## Limit
|
||||
|
||||
`Limit` limits the query result to `n` entities.
|
||||
|
||||
```go
|
||||
users, err := client.User.
|
||||
Query().
|
||||
Limit(n).
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
|
||||
## Offset
|
||||
|
||||
`Offset` sets the first node to return from the query.
|
||||
|
||||
```go
|
||||
users, err := client.User.
|
||||
Query().
|
||||
Offset(10).
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
## Ordering
|
||||
|
||||
`Order` returns the entities sorted by the values of one or more fields. Note that, an error
|
||||
is returned if the given fields are not valid columns or foreign-keys.
|
||||
|
||||
```go
|
||||
users, err := client.User.Query().
|
||||
Order(ent.Asc(user.FieldName)).
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
## Edge Ordering
|
||||
|
||||
In order to sort by fields of an edge (relation), start the traversal from the edge (you want to order by),
|
||||
apply the ordering, and then jump to the neighbours (target type).
|
||||
|
||||
The following shows how to order the users by the `"name"` of their `"pets"` in ascending order.
|
||||
```go
|
||||
users, err := client.Pet.Query().
|
||||
Order(ent.Asc(pet.FieldName)).
|
||||
QueryOwner().
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
## Custom Ordering
|
||||
|
||||
Custom ordering functions can be useful if you want to write your own storage-specific logic.
|
||||
|
||||
The following shows how to order pets by their name, and their owners' name in ascending order.
|
||||
|
||||
```go
|
||||
names, err := client.Pet.Query().
|
||||
Order(func(s *sql.Selector) {
|
||||
// Join with user table for ordering by owner-name and pet-name.
|
||||
t := sql.Table(user.Table)
|
||||
s.Join(t).On(s.C(pet.OwnerColumn), t.C(user.FieldID))
|
||||
s.OrderBy(t.C(user.FieldName), s.C(pet.FieldName))
|
||||
}).
|
||||
Select(pet.FieldName).
|
||||
Strings(ctx)
|
||||
```
|
||||
138
doc/md/paging.mdx
Normal file
138
doc/md/paging.mdx
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
id: paging
|
||||
title: Paging And Ordering
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
## Limit
|
||||
|
||||
`Limit` limits the query result to `n` entities.
|
||||
|
||||
```go
|
||||
users, err := client.User.
|
||||
Query().
|
||||
Limit(n).
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
|
||||
## Offset
|
||||
|
||||
`Offset` sets the first node to return from the query.
|
||||
|
||||
```go
|
||||
users, err := client.User.
|
||||
Query().
|
||||
Offset(10).
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
## Ordering
|
||||
|
||||
`Order` returns the entities sorted by the values of one or more fields. Note that, an error
|
||||
is returned if the given fields are not valid columns or foreign-keys.
|
||||
|
||||
```go
|
||||
users, err := client.User.Query().
|
||||
Order(ent.Asc(user.FieldName)).
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
## Edge Ordering
|
||||
|
||||
In order to sort by fields of an edge (relation), start the traversal from the edge (you want to order by),
|
||||
apply the ordering, and then jump to the neighbours (target type).
|
||||
|
||||
The following shows how to order the users by the `"name"` of their `"pets"` in ascending order.
|
||||
```go
|
||||
users, err := client.Pet.Query().
|
||||
Order(ent.Asc(pet.FieldName)).
|
||||
QueryOwner().
|
||||
All(ctx)
|
||||
```
|
||||
|
||||
## Custom Ordering
|
||||
|
||||
Custom ordering functions can be useful if you want to write your own storage-specific logic.
|
||||
|
||||
The following shows how to order pets by their name, and their owners' name in ascending order.
|
||||
|
||||
```go
|
||||
names, err := client.Pet.Query().
|
||||
Order(func(s *sql.Selector) {
|
||||
// Join with user table for ordering by owner-name and pet-name.
|
||||
t := sql.Table(user.Table)
|
||||
s.Join(t).On(s.C(pet.OwnerColumn), t.C(user.FieldID))
|
||||
s.OrderBy(t.C(user.FieldName), s.C(pet.FieldName))
|
||||
}).
|
||||
Select(pet.FieldName).
|
||||
Strings(ctx)
|
||||
```
|
||||
|
||||
#### Order by JSON fields
|
||||
|
||||
The [`sqljson`](https://pkg.go.dev/entgo.io/ent/dialect/sql/sqljson) package allows to easily sort data based on the
|
||||
value of a JSON object:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="value" label="By Value" default>
|
||||
|
||||
```go {3}
|
||||
users := client.User.Query().
|
||||
Order(
|
||||
sqljson.OrderValue(user.FieldData, sqljson.Path("key1", "key2")),
|
||||
).
|
||||
AllX(ctx)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="length" label="By Length">
|
||||
|
||||
```go {3}
|
||||
users := client.User.Query().
|
||||
Order(
|
||||
sqljson.OrderLen(user.FieldData, sqljson.Path("key1", "key2")),
|
||||
).
|
||||
AllX(ctx)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="desc" label="Descending">
|
||||
|
||||
```go {3,9}
|
||||
users := client.User.Query().
|
||||
Order(
|
||||
sqljson.OrderValueDesc(user.FieldData, sqljson.Path("key1", "key2")),
|
||||
).
|
||||
AllX(ctx)
|
||||
|
||||
pets := client.Pet.Query().
|
||||
Order(
|
||||
sqljson.OrderLenDesc(pet.FieldData, sqljson.Path("key1", "key2")),
|
||||
).
|
||||
AllX(ctx)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<details>
|
||||
<summary>PostgreSQL limitation on <code>ORDER BY</code> expressions with <code>SELECT DISTINCT</code></summary>
|
||||
<div>
|
||||
|
||||
PostgreSQL does not support `ORDER BY` expressions with `SELECT DISTINCT`. Thus, the `Unique` modifier should be set
|
||||
to `false`. However, keep in mind that this may result in duplicate results when performing graph traversals.
|
||||
|
||||
```diff
|
||||
users := client.User.Query().
|
||||
Order(
|
||||
sqljson.OrderValue(user.FieldData, sqljson.Path("key1", "key2")),
|
||||
).
|
||||
+ Unique(false).
|
||||
AllX(ctx)
|
||||
```
|
||||
|
||||
</div>
|
||||
</details>
|
||||
Reference in New Issue
Block a user