feat: support any depth for relationships in findDistinct (#14090)
Follow up to https://github.com/payloadcms/payload/pull/14026 ```ts // Supported before const relationResult = await payload.findDistinct({ collection: 'posts', field: 'relation1.title' }) // Supported now const relationResult = await payload.findDistinct({ collection: 'posts', field: 'relation1.relation2.title' }) const relationResult = await payload.findDistinct({ collection: 'posts', field: 'relation1.relation2.relation3.title' }) ```
This commit is contained in:
@@ -54,6 +54,11 @@ export const getConfig: () => Partial<Config> = () => ({
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
},
|
||||
{
|
||||
name: 'simple',
|
||||
type: 'relationship',
|
||||
relationTo: 'simple',
|
||||
},
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
@@ -131,6 +136,11 @@ export const getConfig: () => Partial<Config> = () => ({
|
||||
name: 'categoryTitle',
|
||||
virtual: 'category.title',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'categorySimpleText',
|
||||
virtual: 'category.simple.text',
|
||||
},
|
||||
{
|
||||
type: 'relationship',
|
||||
relationTo: 'categories',
|
||||
|
||||
@@ -1190,6 +1190,114 @@ describe('database', () => {
|
||||
])
|
||||
})
|
||||
|
||||
it('should find distinct values with field nested to a 2x relationship', async () => {
|
||||
await payload.delete({ collection: 'posts', where: {} })
|
||||
await payload.delete({ collection: 'categories', where: {} })
|
||||
await payload.delete({ collection: 'simple', where: {} })
|
||||
|
||||
const simple_1 = await payload.create({ collection: 'simple', data: { text: 'simple_1' } })
|
||||
const simple_2 = await payload.create({ collection: 'simple', data: { text: 'simple_2' } })
|
||||
const simple_3 = await payload.create({ collection: 'simple', data: { text: 'simple_3' } })
|
||||
|
||||
const category_1 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_1', simple: simple_1 },
|
||||
})
|
||||
const category_2 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_2', simple: simple_2 },
|
||||
})
|
||||
const category_3 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_3', simple: simple_3 },
|
||||
})
|
||||
const category_4 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_4', simple: simple_3 },
|
||||
})
|
||||
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_1 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_2 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_2 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_2 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_4 } })
|
||||
|
||||
const res = await payload.findDistinct({
|
||||
collection: 'posts',
|
||||
field: 'category.simple.text',
|
||||
})
|
||||
|
||||
expect(res.values).toEqual([
|
||||
{
|
||||
'category.simple.text': 'simple_1',
|
||||
},
|
||||
{
|
||||
'category.simple.text': 'simple_2',
|
||||
},
|
||||
{
|
||||
'category.simple.text': 'simple_3',
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('should find distinct values with virtual field linked to a 2x relationship', async () => {
|
||||
await payload.delete({ collection: 'posts', where: {} })
|
||||
await payload.delete({ collection: 'categories', where: {} })
|
||||
await payload.delete({ collection: 'simple', where: {} })
|
||||
|
||||
const simple_1 = await payload.create({ collection: 'simple', data: { text: 'simple_1' } })
|
||||
const simple_2 = await payload.create({ collection: 'simple', data: { text: 'simple_2' } })
|
||||
const simple_3 = await payload.create({ collection: 'simple', data: { text: 'simple_3' } })
|
||||
|
||||
const category_1 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_1', simple: simple_1 },
|
||||
})
|
||||
const category_2 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_2', simple: simple_2 },
|
||||
})
|
||||
const category_3 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_3', simple: simple_3 },
|
||||
})
|
||||
const category_4 = await payload.create({
|
||||
collection: 'categories',
|
||||
data: { title: 'category_4', simple: simple_3 },
|
||||
})
|
||||
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_1 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_2 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_2 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_2 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_3 } })
|
||||
await payload.create({ collection: 'posts', data: { title: 'post', category: category_4 } })
|
||||
|
||||
const res = await payload.findDistinct({
|
||||
collection: 'posts',
|
||||
field: 'categorySimpleText',
|
||||
})
|
||||
|
||||
expect(res.values).toEqual([
|
||||
{
|
||||
categorySimpleText: 'simple_1',
|
||||
},
|
||||
{
|
||||
categorySimpleText: 'simple_2',
|
||||
},
|
||||
{
|
||||
categorySimpleText: 'simple_3',
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
describe('Compound Indexes', () => {
|
||||
beforeEach(async () => {
|
||||
await payload.delete({ collection: 'compound-indexes', where: {} })
|
||||
|
||||
@@ -180,6 +180,7 @@ export interface NoTimeStamp {
|
||||
export interface Category {
|
||||
id: string;
|
||||
title?: string | null;
|
||||
simple?: (string | null) | Simple;
|
||||
hideout?: {
|
||||
camera1?: {
|
||||
time1Image?: (string | null) | Post;
|
||||
@@ -189,6 +190,17 @@ export interface Category {
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "simple".
|
||||
*/
|
||||
export interface Simple {
|
||||
id: string;
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "posts".
|
||||
@@ -198,6 +210,7 @@ export interface Post {
|
||||
title: string;
|
||||
category?: (string | null) | Category;
|
||||
categoryTitle?: string | null;
|
||||
categorySimpleText?: string | null;
|
||||
categories?: (string | Category)[] | null;
|
||||
categoryPoly?: {
|
||||
relationTo: 'categories';
|
||||
@@ -318,17 +331,6 @@ export interface CategoriesCustomId {
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "simple".
|
||||
*/
|
||||
export interface Simple {
|
||||
id: string;
|
||||
text?: string | null;
|
||||
number?: number | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "error-on-unnamed-fields".
|
||||
@@ -838,6 +840,7 @@ export interface NoTimeStampsSelect<T extends boolean = true> {
|
||||
*/
|
||||
export interface CategoriesSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
simple?: T;
|
||||
hideout?:
|
||||
| T
|
||||
| {
|
||||
@@ -879,6 +882,7 @@ export interface PostsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
category?: T;
|
||||
categoryTitle?: T;
|
||||
categorySimpleText?: T;
|
||||
categories?: T;
|
||||
categoryPoly?: T;
|
||||
categoryPolyMany?: T;
|
||||
|
||||
Reference in New Issue
Block a user