4.8 KiB
| title | aliases | tags | sources | created | updated | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Queries — Select & Populate |
|
|
|
2026-05-15 | 2026-05-15 |
Overview
By default Payload returns all fields for every query. The Select API lets you specify exactly which fields to return, reducing DB load and response size.
Include / Exclude Modes
select operates in one of two modes depending on the values you pass:
| Mode | How | Result |
|---|---|---|
| Include | Set fields to true |
Only those fields + id |
| Exclude | Set fields to false |
All fields except those |
// Include mode — only id, text, group.number, array
await payload.find({
collection: 'posts',
select: {
text: true,
group: { number: true },
array: true,
},
})
// Exclude mode — all fields except array and group.number
await payload.find({
collection: 'posts',
select: {
array: false,
group: { number: false },
},
})
Empty select
Always returns only id — the id field is always included regardless of your select.
const post = await payload.findByID({ collection: 'posts', id: '1', select: {} })
// → { id: '1' }
Entity-Level select Config
Both Collections and Globals accept a top-level select function that runs before every read. Use it to force fields into every query regardless of what the caller requests.
export const Posts: CollectionConfig = {
slug: 'posts',
// Always include `title` — required by access control / hooks
select: ({ select }) => (select ? { ...select, title: true } : undefined),
fields: [ /* ... */ ],
}
- Receives
{ operation, req, select }→ returns the finalselectto apply - Replaces (not merges) the caller's select — spread
selectwhen you want to add - Return
undefinedto leave the caller's select untouched - Per-document data is not available (runs before the read)
Warning:
beforeReadandafterReadhooks may not receive the fulldocwhenselectis active. Use entity-level config to guarantee field availability in hooks/access control.
REST API
Use bracket notation in query params; prefer qs-esm for complex queries:
// Direct
fetch('https://localhost:3000/api/posts?select[color]=true&select[group][number]=true')
// With qs-esm (recommended)
import { stringify } from 'qs-esm'
const stringifiedQuery = stringify({ select: { text: true, group: { number: true } } }, { addQueryPrefix: true })
const response = await fetch(`http://localhost:3000/api/posts${stringifiedQuery}`)
Same syntax works for Globals via /api/globals/<slug>.
defaultPopulate — Optimize Relationship Population
Set on a Collection to control which fields are returned when that collection is populated (via Relationship or Upload fields in other documents).
export const Pages: CollectionConfig<'pages'> = {
slug: 'pages',
defaultPopulate: {
slug: true, // only return slug when populated from another doc
},
fields: [{ name: 'slug', type: 'text', required: true }],
}
Warning (Upload fields): If you include
urlindefaultPopulate, you must also includefilename: true, otherwise Payload cannot construct the file URL and returnsurl: null.
populate Override
Override defaultPopulate per-query via the populate option:
// Local API
await payload.find({
collection: 'posts',
populate: {
pages: { text: true }, // overrides defaultPopulate on Pages collection
},
})
// REST API
fetch('https://localhost:3000/api/posts?populate[pages][text]=true')
Key Takeaways
selectis applied at the database level — efficient but means hooks may receive partial docs- Use entity-level
selectfunction to guarantee fields in hooks/access control idis always returned — even withselect: {}defaultPopulateon a Collection drastically reduces JSON from relationship fields — set it for any collection only needed as a reference (e.g. pages linked by slug)- For Upload collections:
defaultPopulatewithurlrequiresfilename: truealongside it - Use
qs-esmfor REST API select/populate — raw bracket notation gets unwieldy fast
Related
- wiki/payloadcms/queries
- wiki/payloadcms/queries-depth
- wiki/payloadcms/queries-pagination
- wiki/payloadcms/fields-relationship
- wiki/payloadcms/fields-upload
- wiki/payloadcms/hooks
- wiki/payloadcms/local-api
- wiki/payloadcms/rest-api
Sources
raw/queries__select.md— https://payloadcms.com/docs/queries/select