Requêtes avancées
Filtres, jointures, pagination, agrégations et temps réel avec le SDK JavaScript.
6.1Filtres
Les filtres les plus utiliséstypescript
// Égalité
const { data } = await supabase
.from('articles')
.select('*')
.eq('published', true) // WHERE published = true
// Différent
.neq('status', 'draft') // WHERE status != 'draft'
// Supérieur / Inférieur
.gt('views', 100) // WHERE views > 100
.gte('views', 100) // WHERE views >= 100
.lt('price', 50) // WHERE price < 50
.lte('price', 50) // WHERE price <= 50
// Contient du texte (LIKE)
.like('title', '%react%') // WHERE title LIKE '%react%'
.ilike('title', '%react%') // Case-insensitive
// Dans une liste (IN)
.in('category', ['tech', 'design', 'business'])
// Null / Not Null
.is('deleted_at', null) // WHERE deleted_at IS NULL
.not('deleted_at', 'is', null) // WHERE deleted_at IS NOT NULL6.2Combiner des filtres (AND / OR)
Filtres combinéstypescript
// AND : chaîner les filtres (par défaut)
const { data } = await supabase
.from('articles')
.select('*')
.eq('published', true)
.eq('category', 'tech')
// → WHERE published = true AND category = 'tech'
// OR : utiliser .or()
const { data: results } = await supabase
.from('articles')
.select('*')
.or('category.eq.tech,category.eq.design')
// → WHERE category = 'tech' OR category = 'design'6.3Sélectionner des colonnes spécifiques
Select partiel = performancetypescript
// Ne récupère que ce dont tu as besoin
const { data } = await supabase
.from('articles')
.select('id, title, created_at')
// Pas besoin de charger le contenu complet pour une liste !
// Renommer une colonne dans le résultat
const { data: items } = await supabase
.from('articles')
.select('id, titre:title, date:created_at')6.4Jointures (relations)
Le SDK Supabase gère les jointures automatiquement grâce aux foreign keys :
Jointure automatique via foreign keytypescript
// Récupérer les articles avec leurs commentaires
const { data } = await supabase
.from('articles')
.select(`
id,
title,
comments (
id,
content,
created_at
)
`)
.eq('published', true)
// Résultat :
// [
// {
// id: '...', title: 'Mon article',
// comments: [
// { id: '...', content: 'Super !', created_at: '...' },
// { id: '...', content: 'Merci', created_at: '...' },
// ]
// }
// ]Jointure inverse : du commentaire vers l'articletypescript
// Récupérer les commentaires avec leur article parent
const { data } = await supabase
.from('comments')
.select(`
id,
content,
articles!article_id (
title
)
`)
.order('created_at', { ascending: false })6.5Tri et pagination
Tritypescript
const { data } = await supabase
.from('articles')
.select('*')
.order('created_at', { ascending: false }) // Plus récent d'abord
.order('title', { ascending: true }) // Puis par titre A-ZPagination : offset-basedtypescript
const PAGE_SIZE = 10
const page = 2 // Page 2
const { data, count } = await supabase
.from('articles')
.select('*', { count: 'exact' }) // Retourne aussi le total
.range((page - 1) * PAGE_SIZE, page * PAGE_SIZE - 1)
// range(10, 19) = lignes 11 à 20
// count = nombre total d'articles (pour calculer le nombre de pages)6.6Compter et agréger
Compter les résultatstypescript
// Compter sans récupérer les données
const { count } = await supabase
.from('articles')
.select('*', { count: 'exact', head: true }) // head: true = pas de data
.eq('published', true)
console.log(`${count} articles publiés`)6.7Temps réel (Realtime)
Supabase Realtime te permet d'écouter les changements sur une table en temps réel via WebSocket :
S'abonner aux changements d'une tabletypescript
const channel = supabase
.channel('articles-changes')
.on(
'postgres_changes',
{ event: '*', schema: 'public', table: 'articles' },
(payload) => {
console.log('Changement :', payload.eventType)
// 'INSERT' | 'UPDATE' | 'DELETE'
console.log('Données :', payload.new)
}
)
.subscribe()
// Plus tard, se désabonner :
supabase.removeChannel(channel)Écouter un seul type d'événementtypescript
// Uniquement les nouvelles insertions pour cet utilisateur
const channel = supabase
.channel('my-notifications')
.on(
'postgres_changes',
{
event: 'INSERT',
schema: 'public',
table: 'notifications',
filter: `user_id=eq.${user.id}`,
},
(payload) => {
showNotification(payload.new)
}
)
.subscribe()