Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/database/indexes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ export const MyCollection: CollectionConfig = {
}
```

## Unique Fields

Setting `unique: true` on a field creates a **collection-wide** database unique index on that field's path. This means no two documents in the collection can share the same value for that field.

<Banner type="warning">
**Using `unique` on fields nested inside `array` or `blocks`** creates a
collection-wide unique index on the dotted path (e.g. `items.key`). This is
**not** the same as enforcing uniqueness within a single document's array rows
— it prevents *any two documents* from having the same value at that path.

Additionally, on **MongoDB**, documents that do not contain the array will all
share a `null` value at that path. Because unique indexes treat multiple
`null` values as duplicates, saving a second document without the array will
fail with a validation error.

If you need to enforce uniqueness _within_ a document's array rows (e.g. no
duplicate keys in the same document), use a custom
[`validate`](/docs/fields/overview#validation) function on the array field
instead.

</Banner>

## Localized fields and MongoDB indexes

When you set `index: true` or `unique: true` on a localized field, MongoDB creates one index **per locale path** (e.g., `slug.en`, `slug.da-dk`, etc.). With many locales and indexed fields, this can quickly approach MongoDB's per-collection index limit.
Expand Down
52 changes: 31 additions & 21 deletions docs/fields/array.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,41 @@ export const MyArrayField: Field = {

## Config Options

| Option | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More details](/docs/fields/overview#field-names). |
| **`label`** | Text used as the heading in the [Admin Panel](../admin/overview) or an object with keys for each language. Auto-generated from name if not defined. |
| **`fields`** \* | Array of field types to correspond to each row of the Array. |
| **`validate`** | Provide a custom validation function that will be executed on both the [Admin Panel](../admin/overview) and the backend. [More details](/docs/fields/overview#validation). |
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide an array of row data to be used for this field's default value. [More details](/docs/fields/overview#default-values). |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as `localized`. |
| **`required`** | Require this field to have a value. |
| **`labels`** | Customize the row labels appearing in the Admin dashboard. |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
| **`dbName`** | Custom table name for the field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
| Option | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More details](/docs/fields/overview#field-names). |
| **`label`** | Text used as the heading in the [Admin Panel](../admin/overview) or an object with keys for each language. Auto-generated from name if not defined. |
| **`fields`** \* | Array of field types to correspond to each row of the Array. |
| **`validate`** | Provide a custom validation function that will be executed on both the [Admin Panel](../admin/overview) and the backend. [More details](/docs/fields/overview#validation). |
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
| **`defaultValue`** | Provide an array of row data to be used for this field's default value. [More details](/docs/fields/overview#default-values). |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as `localized`. |
| **`required`** | Require this field to have a value. |
| **`labels`** | Customize the row labels appearing in the Admin dashboard. |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
| **`dbName`** | Custom table name for the field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/overview#string-path-virtual-fields). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |

_\* An asterisk denotes that a property is required._

<Banner type="warning">
Setting `unique: true` on a field **inside** an Array creates a
collection-wide database unique index — not a per-document one. No two
documents in the collection can share the same value at that nested path, and
on MongoDB, documents without the array will collide on `null`. To enforce
uniqueness within a single document's rows, use a custom
[`validate`](/docs/fields/overview#validation) function on this Array field.
[More details](/docs/database/indexes#unique-fields).
</Banner>

## Admin Options

To customize the appearance and behavior of the Array Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
Expand Down
14 changes: 12 additions & 2 deletions docs/fields/blocks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ This page is divided into two parts: first, the settings of the Blocks Field, an
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API response or the Admin Panel. |
| **`defaultValue`** | Provide an array of block data to be used for this field's default value. [More details](/docs/fields/overview#default-values). |
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this field will be kept, so there is no need to specify each nested field as `localized`. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. This creates a database-level unique index on the field's path. [More details](/docs/database/indexes#unique-fields). |
| **`labels`** | Customize the block row labels appearing in the Admin dashboard. |
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
Expand All @@ -65,6 +65,16 @@ This page is divided into two parts: first, the settings of the Blocks Field, an

_\* An asterisk denotes that a property is required._

<Banner type="warning">
Setting `unique: true` on a field **inside** a Block creates a collection-wide
database unique index — not a per-document one. No two documents in the
collection can share the same value at that nested path, and on MongoDB,
documents without the block will collide on `null`. To enforce uniqueness
within a single document's blocks, use a custom
[`validate`](/docs/fields/overview#validation) function on this Blocks field.
[More details](/docs/database/indexes#unique-fields).
</Banner>

### Block Admin Options

To customize the appearance and behavior of the Blocks Field in the [Admin Panel](../admin/overview), you can use the `admin` option:
Expand Down Expand Up @@ -506,7 +516,7 @@ Blocks can be conditionally enabled using the `filterOptions` property on the bl
- `filterOptions` is re-evaluated as part of the form state request, whenever the document data changes.
- If a block is present in the field but no longer allowed by `filterOptions`, a validation error will occur when saving.

### Example
### filterOptions Example

```ts
{
Expand Down
Loading
Loading