feat(db-mongodb): support sorting by fields in other collections through a relationship field (#11803)
This is already supported in Postgres / SQLite.
For example:
```
const result = await payload.find({
collection: 'directors',
depth: 0,
sort: '-movies.name', // movies is a relationship field here
})
```
Removes the condition in tests:
```
// no support for sort by relation in mongodb
if (isMongoose(payload)) {
return
}
```
This commit is contained in:
@@ -223,6 +223,7 @@ export default buildConfigWithDefaults({
|
||||
},
|
||||
{
|
||||
slug: 'movies',
|
||||
versions: { drafts: true },
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
@@ -242,6 +243,11 @@ export default buildConfigWithDefaults({
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'localized',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'movies',
|
||||
type: 'relationship',
|
||||
|
||||
@@ -593,11 +593,6 @@ describe('Relationships', () => {
|
||||
})
|
||||
|
||||
it('should sort by a property of a hasMany relationship', async () => {
|
||||
// no support for sort by relation in mongodb
|
||||
if (isMongoose(payload)) {
|
||||
return
|
||||
}
|
||||
|
||||
const movie1 = await payload.create({
|
||||
collection: 'movies',
|
||||
data: {
|
||||
@@ -638,6 +633,92 @@ describe('Relationships', () => {
|
||||
expect(result.docs[0].id).toStrictEqual(director1.id)
|
||||
})
|
||||
|
||||
it('should sort by a property of a relationship', async () => {
|
||||
await payload.delete({ collection: 'directors', where: {} })
|
||||
await payload.delete({ collection: 'movies', where: {} })
|
||||
|
||||
const director_1 = await payload.create({
|
||||
collection: 'directors',
|
||||
data: { name: 'Dan', localized: 'Dan' },
|
||||
})
|
||||
|
||||
await payload.update({
|
||||
collection: 'directors',
|
||||
id: director_1.id,
|
||||
locale: 'de',
|
||||
data: { localized: 'Mr. Dan' },
|
||||
})
|
||||
|
||||
const director_2 = await payload.create({
|
||||
collection: 'directors',
|
||||
data: { name: 'Mr. Dan', localized: 'Mr. Dan' },
|
||||
})
|
||||
|
||||
await payload.update({
|
||||
collection: 'directors',
|
||||
id: director_2.id,
|
||||
locale: 'de',
|
||||
data: { localized: 'Dan' },
|
||||
})
|
||||
|
||||
const movie_1 = await payload.create({
|
||||
collection: 'movies',
|
||||
depth: 0,
|
||||
data: { director: director_1.id, name: 'Some Movie 1' },
|
||||
})
|
||||
|
||||
const movie_2 = await payload.create({
|
||||
collection: 'movies',
|
||||
depth: 0,
|
||||
data: { director: director_2.id, name: 'Some Movie 2' },
|
||||
})
|
||||
|
||||
const res_1 = await payload.find({
|
||||
collection: 'movies',
|
||||
sort: '-director.name',
|
||||
depth: 0,
|
||||
})
|
||||
const res_2 = await payload.find({
|
||||
collection: 'movies',
|
||||
sort: 'director.name',
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
expect(res_1.docs).toStrictEqual([movie_2, movie_1])
|
||||
expect(res_2.docs).toStrictEqual([movie_1, movie_2])
|
||||
|
||||
const draft_res_1 = await payload.find({
|
||||
collection: 'movies',
|
||||
sort: '-director.name',
|
||||
depth: 0,
|
||||
draft: true,
|
||||
})
|
||||
const draft_res_2 = await payload.find({
|
||||
collection: 'movies',
|
||||
sort: 'director.name',
|
||||
depth: 0,
|
||||
draft: true,
|
||||
})
|
||||
|
||||
expect(draft_res_1.docs).toStrictEqual([movie_2, movie_1])
|
||||
expect(draft_res_2.docs).toStrictEqual([movie_1, movie_2])
|
||||
|
||||
const localized_res_1 = await payload.find({
|
||||
collection: 'movies',
|
||||
sort: 'director.localized',
|
||||
depth: 0,
|
||||
locale: 'de',
|
||||
})
|
||||
const localized_res_2 = await payload.find({
|
||||
collection: 'movies',
|
||||
sort: 'director.localized',
|
||||
depth: 0,
|
||||
})
|
||||
|
||||
expect(localized_res_1.docs).toStrictEqual([movie_2, movie_1])
|
||||
expect(localized_res_2.docs).toStrictEqual([movie_1, movie_2])
|
||||
})
|
||||
|
||||
it('should query using "in" by hasMany relationship field', async () => {
|
||||
const tree1 = await payload.create({
|
||||
collection: treeSlug,
|
||||
|
||||
@@ -54,6 +54,7 @@ export type SupportedTimezones =
|
||||
| 'Asia/Singapore'
|
||||
| 'Asia/Tokyo'
|
||||
| 'Asia/Seoul'
|
||||
| 'Australia/Brisbane'
|
||||
| 'Australia/Sydney'
|
||||
| 'Pacific/Guam'
|
||||
| 'Pacific/Noumea'
|
||||
@@ -268,6 +269,7 @@ export interface Movie {
|
||||
director?: (string | null) | Director;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
@@ -276,6 +278,7 @@ export interface Movie {
|
||||
export interface Director {
|
||||
id: string;
|
||||
name?: string | null;
|
||||
localized?: string | null;
|
||||
movies?: (string | Movie)[] | null;
|
||||
directors?: (string | Director)[] | null;
|
||||
updatedAt: string;
|
||||
@@ -460,9 +463,10 @@ export interface Item {
|
||||
id: string;
|
||||
status?: ('completed' | 'failed' | 'pending') | null;
|
||||
relation?: {
|
||||
docs?: (string | Relation1)[] | null;
|
||||
hasNextPage?: boolean | null;
|
||||
} | null;
|
||||
docs?: (string | Relation1)[];
|
||||
hasNextPage?: boolean;
|
||||
totalDocs?: number;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
@@ -728,6 +732,7 @@ export interface MoviesSelect<T extends boolean = true> {
|
||||
director?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
_status?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
@@ -735,6 +740,7 @@ export interface MoviesSelect<T extends boolean = true> {
|
||||
*/
|
||||
export interface DirectorsSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
localized?: T;
|
||||
movies?: T;
|
||||
directors?: T;
|
||||
updatedAt?: T;
|
||||
|
||||
Reference in New Issue
Block a user