feat: add indexSortableField option to create indexes for sortable fields on all collections
This commit is contained in:
@@ -130,6 +130,7 @@ export default buildConfig({
|
|||||||
defaultLocale: 'en',
|
defaultLocale: 'en',
|
||||||
fallback: true,
|
fallback: true,
|
||||||
},
|
},
|
||||||
|
// indexSortableFields: true,
|
||||||
hooks: {
|
hooks: {
|
||||||
afterError: (err) => {
|
afterError: (err) => {
|
||||||
console.error('global error config handler', err);
|
console.error('global error config handler', err);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ Payload is a *config-based*, code-first CMS and application framework. The Paylo
|
|||||||
| `csrf` | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More](/docs/authentication/overview#csrf-protection) |
|
| `csrf` | A whitelist array of URLs to allow Payload cookies to be accepted from as a form of CSRF protection. [More](/docs/authentication/overview#csrf-protection) |
|
||||||
| `defaultDepth` | If a user does not specify `depth` while requesting a resource, this depth will be used. [More](/docs/getting-started/concepts#depth) |
|
| `defaultDepth` | If a user does not specify `depth` while requesting a resource, this depth will be used. [More](/docs/getting-started/concepts#depth) |
|
||||||
| `maxDepth` | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
| `maxDepth` | The maximum allowed depth to be permitted application-wide. This setting helps prevent against malicious queries. Defaults to `10`. |
|
||||||
|
| `indexSortableFields`| Automatically create database an index on every sortable type of top-level field. |
|
||||||
| `upload` | Base Payload upload configuration. [More](/docs/upload/overview#payload-wide-upload-options). |
|
| `upload` | Base Payload upload configuration. [More](/docs/upload/overview#payload-wide-upload-options). |
|
||||||
| `routes` | Control the routing structure that Payload binds itself to. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. |
|
| `routes` | Control the routing structure that Payload binds itself to. Specify `admin`, `api`, `graphQL`, and `graphQLPlayground`. |
|
||||||
| `email` | Base email settings to allow Payload to generate email such as Forgot Password requests and other requirements. [More](/docs/email/overview#configuration) |
|
| `email` | Base email settings to allow Payload to generate email such as Forgot Password requests and other requirements. [More](/docs/email/overview#configuration) |
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ If you are using a [persistent filesystem-based cloud host](#persistent-vs-ephem
|
|||||||
|
|
||||||
Alternatively, you can rely on a third-party MongoDB host such as [MongoDB Atlas](https://www.mongodb.com/). With Atlas or a similar cloud provider, you can trust them to take care of your database's availability, security, redundancy, and backups.
|
Alternatively, you can rely on a third-party MongoDB host such as [MongoDB Atlas](https://www.mongodb.com/). With Atlas or a similar cloud provider, you can trust them to take care of your database's availability, security, redundancy, and backups.
|
||||||
|
|
||||||
|
When using Azure Cosmos, MongoDB requires an index on any field being sorted on in a query. To make this easier, see the [indexSortableFields](/docs/configuration/overview) configuration option.
|
||||||
|
|
||||||
## File storage
|
## File storage
|
||||||
|
|
||||||
If you are using Payload to [manage file uploads](/docs/upload/overview), you need to consider where your uploaded files will be permanently stored. If you do not use Payload for file uploads, then this section does not impact your app whatsoever.
|
If you are using Payload to [manage file uploads](/docs/upload/overview), you need to consider where your uploaded files will be permanently stored. If you do not use Payload for file uploads, then this section does not impact your app whatsoever.
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export default joi.object({
|
|||||||
}),
|
}),
|
||||||
local: joi.boolean(),
|
local: joi.boolean(),
|
||||||
upload: joi.object(),
|
upload: joi.object(),
|
||||||
|
indexSortableFields: joi.boolean(),
|
||||||
rateLimit: joi.object()
|
rateLimit: joi.object()
|
||||||
.keys({
|
.keys({
|
||||||
window: joi.number(),
|
window: joi.number(),
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ export type Config = {
|
|||||||
},
|
},
|
||||||
defaultDepth?: number;
|
defaultDepth?: number;
|
||||||
maxDepth?: number;
|
maxDepth?: number;
|
||||||
|
indexSortableFields?: boolean;
|
||||||
rateLimit?: {
|
rateLimit?: {
|
||||||
window?: number;
|
window?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
@@ -143,7 +144,7 @@ export type Config = {
|
|||||||
hooks?: {
|
hooks?: {
|
||||||
afterError?: AfterErrorHook;
|
afterError?: AfterErrorHook;
|
||||||
};
|
};
|
||||||
plugins?: Plugin[]
|
plugins?: Plugin[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SanitizedConfig = Omit<DeepRequired<Config>, 'collections' | 'globals'> & {
|
export type SanitizedConfig = Omit<DeepRequired<Config>, 'collections' | 'globals'> & {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const buildModel = (config: SanitizedConfig): mongoose.PaginateModel<any> | null
|
|||||||
const Globals = mongoose.model('globals', globalsSchema);
|
const Globals = mongoose.model('globals', globalsSchema);
|
||||||
|
|
||||||
Object.values(config.globals).forEach((globalConfig) => {
|
Object.values(config.globals).forEach((globalConfig) => {
|
||||||
const globalSchema = buildSchema(config, globalConfig.fields, {});
|
const globalSchema = buildSchema(config, globalConfig.fields, { global: true });
|
||||||
Globals.discriminator(globalConfig.slug, globalSchema);
|
Globals.discriminator(globalConfig.slug, globalSchema);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
import { Schema, SchemaDefinition, SchemaOptions } from 'mongoose';
|
import { Schema, SchemaDefinition, SchemaOptions } from 'mongoose';
|
||||||
import { SanitizedConfig } from '../config/types';
|
import { SanitizedConfig } from '../config/types';
|
||||||
import { ArrayField, Block, BlockField, Field, GroupField, RadioField, RelationshipField, RowField, SelectField, UploadField } from '../fields/config/types';
|
import { ArrayField, Block, BlockField, Field, GroupField, RadioField, RelationshipField, RowField, SelectField, UploadField } from '../fields/config/types';
|
||||||
|
import sortableFieldTypes from '../fields/sortableFieldTypes';
|
||||||
|
|
||||||
type BuildSchemaOptions = {
|
type BuildSchemaOptions = {
|
||||||
options?: SchemaOptions
|
options?: SchemaOptions
|
||||||
allowIDField?: boolean
|
allowIDField?: boolean
|
||||||
disableRequired?: boolean
|
disableRequired?: boolean
|
||||||
|
global?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type FieldSchemaGenerator = (field: Field, fields: SchemaDefinition, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions) => SchemaDefinition;
|
type FieldSchemaGenerator = (field: Field, fields: SchemaDefinition, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions) => SchemaDefinition;
|
||||||
@@ -89,10 +91,15 @@ const buildSchema = (config: SanitizedConfig, configFields: Field[], buildSchema
|
|||||||
if (fieldSchema) {
|
if (fieldSchema) {
|
||||||
fields = fieldSchema(field, fields, config, buildSchemaOptions);
|
fields = fieldSchema(field, fields, config, buildSchemaOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// geospatial field index must be created after the schema is created
|
// geospatial field index must be created after the schema is created
|
||||||
if (fieldIndexMap[field.type]) {
|
if (fieldIndexMap[field.type]) {
|
||||||
indexFields.push(...fieldIndexMap[field.type](field, config));
|
indexFields.push(...fieldIndexMap[field.type](field, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.indexSortableFields && !buildSchemaOptions.global && !field.index && !field.hidden && sortableFieldTypes.indexOf(field.type) > -1) {
|
||||||
|
indexFields.push({ [field.name]: 1 });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const schema = new Schema(fields, options);
|
const schema = new Schema(fields, options);
|
||||||
|
|||||||
Reference in New Issue
Block a user