feat(db-*): support sort in db.updateMany (#11768)
This adds support for `sort` in `payload.db.updateMany`.
## Example
```ts
const updatedDocs = await payload.db.updateMany({
collection: 'posts',
data: {
title: 'updated',
},
limit: 5,
sort: '-numberField', // <= new
where: {
id: {
exists: true,
},
},
})
```
This commit is contained in:
@@ -82,7 +82,7 @@ export interface Config {
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
defaultIDType: number;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
@@ -118,7 +118,7 @@ export interface UserAuthOperations {
|
||||
* via the `definition` "posts".
|
||||
*/
|
||||
export interface Post {
|
||||
id: string;
|
||||
id: number;
|
||||
title?: string | null;
|
||||
description?: string | null;
|
||||
defaultValueField?: string | null;
|
||||
@@ -155,7 +155,7 @@ export interface Post {
|
||||
* via the `definition` "users".
|
||||
*/
|
||||
export interface User {
|
||||
id: string;
|
||||
id: number;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
@@ -172,20 +172,20 @@ export interface User {
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
id: number;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'posts';
|
||||
value: string | Post;
|
||||
value: number | Post;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
value: number | User;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
value: number | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
@@ -195,10 +195,10 @@ export interface PayloadLockedDocument {
|
||||
* via the `definition` "payload-preferences".
|
||||
*/
|
||||
export interface PayloadPreference {
|
||||
id: string;
|
||||
id: number;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
value: number | User;
|
||||
};
|
||||
key?: string | null;
|
||||
value?:
|
||||
@@ -218,7 +218,7 @@ export interface PayloadPreference {
|
||||
* via the `definition` "payload-migrations".
|
||||
*/
|
||||
export interface PayloadMigration {
|
||||
id: string;
|
||||
id: number;
|
||||
name?: string | null;
|
||||
batch?: number | null;
|
||||
updatedAt: string;
|
||||
|
||||
@@ -44,6 +44,10 @@ export default buildConfigWithDefaults({
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'number',
|
||||
type: 'number',
|
||||
},
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
|
||||
@@ -317,7 +317,7 @@ describe('database', () => {
|
||||
payload.config.db.allowIDOnCreate = false
|
||||
})
|
||||
|
||||
it('Local API - accepts ID on create', async () => {
|
||||
it('local API - accepts ID on create', async () => {
|
||||
let id: any = null
|
||||
if (payload.db.name === 'mongoose') {
|
||||
id = new mongoose.Types.ObjectId().toHexString()
|
||||
@@ -332,7 +332,7 @@ describe('database', () => {
|
||||
expect(post.id).toBe(id)
|
||||
})
|
||||
|
||||
it('REST API - accepts ID on create', async () => {
|
||||
it('rEST API - accepts ID on create', async () => {
|
||||
let id: any = null
|
||||
if (payload.db.name === 'mongoose') {
|
||||
id = new mongoose.Types.ObjectId().toHexString()
|
||||
@@ -354,7 +354,7 @@ describe('database', () => {
|
||||
expect(post.doc.id).toBe(id)
|
||||
})
|
||||
|
||||
it('GraphQL - accepts ID on create', async () => {
|
||||
it('graphQL - accepts ID on create', async () => {
|
||||
let id: any = null
|
||||
if (payload.db.name === 'mongoose') {
|
||||
id = new mongoose.Types.ObjectId().toHexString()
|
||||
@@ -1168,6 +1168,140 @@ describe('database', () => {
|
||||
expect(notUpdatedDocs?.[5]?.title).toBe('not updated')
|
||||
})
|
||||
|
||||
it('ensure updateMany respects limit and sort', async () => {
|
||||
await payload.db.deleteMany({
|
||||
collection: postsSlug,
|
||||
where: {
|
||||
id: {
|
||||
exists: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const numbers = Array.from({ length: 11 }, (_, i) => i)
|
||||
|
||||
// shuffle the numbers
|
||||
numbers.sort(() => Math.random() - 0.5)
|
||||
|
||||
// create 11 documents numbered 0-10, but in random order
|
||||
for (const i of numbers) {
|
||||
await payload.create({
|
||||
collection: postsSlug,
|
||||
data: {
|
||||
title: 'not updated',
|
||||
number: i,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const result = await payload.db.updateMany({
|
||||
collection: postsSlug,
|
||||
data: {
|
||||
title: 'updated',
|
||||
},
|
||||
limit: 5,
|
||||
sort: 'number',
|
||||
where: {
|
||||
id: {
|
||||
exists: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(result?.length).toBe(5)
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
expect(result?.[i]?.number).toBe(i)
|
||||
expect(result?.[i]?.title).toBe('updated')
|
||||
}
|
||||
|
||||
// Ensure all posts minus the one we don't want updated are updated
|
||||
const { docs } = await payload.find({
|
||||
collection: postsSlug,
|
||||
depth: 0,
|
||||
pagination: false,
|
||||
sort: 'number',
|
||||
where: {
|
||||
title: {
|
||||
equals: 'updated',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(docs).toHaveLength(5)
|
||||
for (let i = 0; i < 5; i++) {
|
||||
expect(docs?.[i]?.number).toBe(i)
|
||||
expect(docs?.[i]?.title).toBe('updated')
|
||||
}
|
||||
})
|
||||
|
||||
it('ensure updateMany respects limit and negative sort', async () => {
|
||||
await payload.db.deleteMany({
|
||||
collection: postsSlug,
|
||||
where: {
|
||||
id: {
|
||||
exists: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const numbers = Array.from({ length: 11 }, (_, i) => i)
|
||||
|
||||
// shuffle the numbers
|
||||
numbers.sort(() => Math.random() - 0.5)
|
||||
|
||||
// create 11 documents numbered 0-10, but in random order
|
||||
for (const i of numbers) {
|
||||
await payload.create({
|
||||
collection: postsSlug,
|
||||
data: {
|
||||
title: 'not updated',
|
||||
number: i,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const result = await payload.db.updateMany({
|
||||
collection: postsSlug,
|
||||
data: {
|
||||
title: 'updated',
|
||||
},
|
||||
limit: 5,
|
||||
sort: '-number',
|
||||
where: {
|
||||
id: {
|
||||
exists: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(result?.length).toBe(5)
|
||||
|
||||
for (let i = 10; i > 5; i--) {
|
||||
expect(result?.[-i + 10]?.number).toBe(i)
|
||||
expect(result?.[-i + 10]?.title).toBe('updated')
|
||||
}
|
||||
|
||||
// Ensure all posts minus the one we don't want updated are updated
|
||||
const { docs } = await payload.find({
|
||||
collection: postsSlug,
|
||||
depth: 0,
|
||||
pagination: false,
|
||||
sort: '-number',
|
||||
where: {
|
||||
title: {
|
||||
equals: 'updated',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(docs).toHaveLength(5)
|
||||
for (let i = 10; i > 5; i--) {
|
||||
expect(docs?.[-i + 10]?.number).toBe(i)
|
||||
expect(docs?.[-i + 10]?.title).toBe('updated')
|
||||
}
|
||||
})
|
||||
|
||||
it('ensure updateMany correctly handles 0 limit', async () => {
|
||||
await payload.db.deleteMany({
|
||||
collection: postsSlug,
|
||||
|
||||
@@ -54,6 +54,7 @@ export type SupportedTimezones =
|
||||
| 'Asia/Singapore'
|
||||
| 'Asia/Tokyo'
|
||||
| 'Asia/Seoul'
|
||||
| 'Australia/Brisbane'
|
||||
| 'Australia/Sydney'
|
||||
| 'Pacific/Guam'
|
||||
| 'Pacific/Noumea'
|
||||
@@ -151,6 +152,7 @@ export interface UserAuthOperations {
|
||||
export interface Post {
|
||||
id: string;
|
||||
title: string;
|
||||
number?: number | null;
|
||||
D1?: {
|
||||
D2?: {
|
||||
D3?: {
|
||||
@@ -545,6 +547,7 @@ export interface PayloadMigration {
|
||||
*/
|
||||
export interface PostsSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
number?: T;
|
||||
D1?:
|
||||
| T
|
||||
| {
|
||||
|
||||
Reference in New Issue
Block a user