How to structure content in Sanity.io & use GROQ queries for filtering & referencing related documents.
import {RiUserLine as icon} from 'react-icons/ri'
export default {
title: 'Directors',
name: 'directors',
type: 'document',
icon,
fields: [
{
title: 'Name',
name: 'name',
type: 'string',
},
{
title: 'Slug',
name: 'slug',
type: 'slug',
description: 'Click on *Generate* to create the slug',
options: {
source: 'name',
slugify: (input) => input.toLowerCase().replace(/\s+/g, '-').slice(0, 200),
},
},
{
title: 'Related Films',
name: 'relatedFilms',
type: 'array',
description: "Reference the director's films you want to showcase",
of: [
{
type: 'reference',
to: [{type: 'films'}],
options: {
filter: ({document}) => {
return {
filter: 'director == $director',
params: {director: document.name},
}
},
},
},
],
},
],
}*[_type == "director"]{
...,
*[_type == "film" && references(^._id)][0..2] | order(date desc)
}^.to reference the parent document:
https://www.sanity.io/docs/reference-type#8118f73f6758
And the lists would be in sync with your content and would not need to be kept up to date
of: [
{
type: 'reference',
to: [{type: 'films'}],
options: {
filter: 'director.name == $directorName',
filterParams: {directorName: '^.name'},
},
},
],is it correlated with the fact that when i inspect my API response of a film, the director field does not contain any data but a _ref and and _type? which is odd, because there is
of: [
{
type: 'reference',
to: [{type: 'films'}],
options: {
filter: 'director._ref == $directorId',
filterParams: { directorId: '^._id' }
}
},
],you have directors and films. each film has a director it references. On the director doc you add a pane where you groq all the films, that reference the director.
Adding 2 way references will make your data structure very cumbersome in the end. This is why loading the references dynamically in a list like this is better!
In addition you can set up a custom structure, where you filter the films to their refrerenced directors. You do not need the array!
// structure
S.listItem()
.title('Films')
.schemaType('film')
.child(
S.documentList()
.title('Film by Director')
.filter('_type == "director"')
.child(
(directorId) =>
S.documentList()
.title('Films')
.filter('_type == "film" && director._ref == $directorId')
.params({ directorId })
.menuItems(S.documentTypeList('film').getMenuItems())
.canHandleIntent(
S.documentTypeList('film').getCanHandleIntent()
)
)
.defaultOrdering([{ field: 'title', direction: 'asc' }])
)this guide here if you want
Was this answer helpful?
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.