Release 1.15.3

Version v1.15.3Patch Release
Released:

September 5, 2023

Type:

Bug fixes and improvements

GitHub:View Release

Release Notes

1.15.3 (2023-09-05)

Bug Fixes

  • draft globals always displaying unpublish button (9bc072c)
  • globals not saving updatedAt and createdAt and version dates correctly (9fbabc8)

Features

✨ Improving version enabled query speed (related PR)

  1. ➡️ Copy migration script below
  2. ➡️ Run migration script
  3. ➡️ Add new property to config
  4. 🧠 While this migration script is very basic, it is always a good idea to backup your DB before running migrations

1. The migration script

```ts
const payload = require('payload');

require('dotenv').config();

const { PAYLOAD_SECRET, MONGODB_URI } = process.env;

// This function adds a latest flag for each documents newest version
// to improve query performance on versions/drafts
const improveVersionsQueryPerformance = async () => {
// Initialize Payload
// IMPORTANT: make sure your ENV variables are filled properly here
// as the below variable names are just for reference.
await payload.init({
secret: PAYLOAD_SECRET,
mongoURL: MONGODB_URI,
local: true,
});

async function migrateCollectionDocs(slug: string, docsAtATime = 100) {
const VersionsModel = payload.versions[slug];
const remainingDocs = await VersionsModel.aggregate([
// Sort so that newest are first
{
$sort: {
updatedAt: -1,
},
},
// Group by parent ID
// take the $first of each
{
$group: {
_id: '$parent',
_versionID: { $first: '$_id' },
version: { $first: '$version' },
updatedAt: { $first: '$updatedAt' },
createdAt: { $first: '$createdAt' },
latest: { $first: '$latest' },
},
},
{
$match: {
latest: { $eq: null },
},
},
{
$limit: docsAtATime,
},
], {
allowDiskUse: true,
})
.exec();

if (!remainingDocs || remainingDocs.length === 0) {
const newVersions = await VersionsModel.find({
latest: {
$eq: true
}
})

if (newVersions?.length) {
console.log(Migrated ${newVersions.length} documents in the "${slug}" versions collection.)
}

return;
}

const remainingDocIds = remainingDocs.map((doc) => doc._versionID);

await VersionsModel.updateMany(
{
_id: {
$in: remainingDocIds,
},
},
{
latest: true,
},
);

await migrateCollectionDocs(slug);
}

// For each collection
await Promise.all(
payload.config.collections.map(async ({ slug, versions }) => {
if (versions) {
return migrateCollectionDocs(slug);
}
}),
);

// For each global
await Promise.all(
payload.config.globals.map(async ({ slug, versions }) => {
if (versions) {
const VersionsModel = payload.versions[slug];

await VersionsModel.findOneAndUpdate(
{},
{ latest: true },
{
sort: { updatedAt: -1 },
},
).exec();

console.log(Migrated the "${slug}" global.)
}
}),
);

console.log('Done!');
process.exit(0);
};

improveVersionsQueryPerformance();
```

2. Running the script

This step depends on where the script is run from and where you place the script. The example below is assuming you have a similar folder structure and are running it from the root folder:

```
root
└─ scripts
└─ improveVersionsQueryPerformance.ts
└─ src
└─ payload.config.ts
```

```bash

the command to run in the root folder

PAYLOAD_CONFIG_PATH=src/payload.config.ts npx ts-node -T scripts/improveVersionsQueryPerformance.ts
```

3. Adjusting your payload.config.ts file

```ts
// file: payload.config.ts

const config = {
// ... rest of your config
database: {
// You can toggle this feature on/off after running the migration
// if you need to revert to querying the previous way
queryDrafts_2_0: true
}
}
```