Aller au contenu

CouchDB : bases et documents

Exemples avec la base fictive boutique (documents client et commande). COUCH=http://127.0.0.1:5984 et identifiants dans ~/.netrc (voir Utilisation en console).

Fenêtre de terminal
curl -sn -X PUT "$COUCH/boutique" # créer
curl -sn "$COUCH/boutique" | jq . # informations
curl -sn "$COUCH/_all_dbs" | jq .
curl -sn -X DELETE "$COUCH/essai" # supprimer (définitif)
curl -sn -X PUT "$COUCH/archives?q=1&n=1" # paramètres de partitionnement

Noms de bases : minuscules, chiffres et _$()+-/, commençant par une lettre.

Un document est un objet JSON. Les champs _id (identifiant) et _rev (révision) sont gérés par CouchDB.

Fenêtre de terminal
# Identifiant choisi
curl -sn -X PUT "$COUCH/boutique/client-1" \
-H 'Content-Type: application/json' \
-d '{"type":"client","nom":"Alice","email":"alice@exemple.com","actif":true}'
# Identifiant généré par CouchDB
curl -sn -X POST "$COUCH/boutique" \
-H 'Content-Type: application/json' \
-d '{"type":"client","nom":"Bob","email":"bob@exemple.com"}'
# Lire
curl -sn "$COUCH/boutique/client-1" | jq .

Bonnes pratiques pour les identifiants :

  • Choisir un identifiant significatif quand c’est possible (client-alice, commande-2026-0042) : la lecture directe est le moyen le plus rapide.
  • Sinon, laisser CouchDB en générer (POST) ou utiliser GET /_uuids.
  • Ajouter un champ "type" pour distinguer les familles de documents d’une même base.

Chaque modification crée une nouvelle révision. Pour modifier, renvoyer le document complet avec le _rev actuel :

Fenêtre de terminal
curl -sn "$COUCH/boutique/client-1" | jq .
# {"_id":"client-1","_rev":"1-967a…","type":"client","nom":"Alice",…}
curl -sn -X PUT "$COUCH/boutique/client-1" \
-H 'Content-Type: application/json' \
-d '{"_rev":"1-967a00dff5e02add41819138abb3284d","type":"client","nom":"Alice Martin","email":"alice@exemple.com","actif":true}'

Script de modification d’un champ avec jq :

Fenêtre de terminal
doc=$(curl -sn "$COUCH/boutique/client-1")
echo "$doc" | jq '.actif = false' \
| curl -sn -X PUT "$COUCH/boutique/client-1" -H 'Content-Type: application/json' -d @-

Une modification avec un _rev périmé est refusée :

{ "error": "conflict", "reason": "Document update conflict." }

Cela protège contre l’écrasement involontaire (accès concurrents) : relire le document, réappliquer la modification, renvoyer. Cette concurrence optimiste est au cœur du fonctionnement de CouchDB.

Fenêtre de terminal
curl -sn -X DELETE "$COUCH/boutique/client-1?rev=2-ab12…"

La suppression crée une « pierre tombale » (_deleted: true) conservée pour la réplication. Pour supprimer en masse, voir _bulk_docs.

Fenêtre de terminal
curl -sn -X POST "$COUCH/boutique/_bulk_docs" \
-H 'Content-Type: application/json' \
-d '{"docs":[
{"_id":"client-2","type":"client","nom":"Chloé"},
{"_id":"client-3","type":"client","nom":"Dan"},
{"_id":"client-1","_rev":"2-ab12…","_deleted":true}
]}' | jq .

La réponse indique, pour chaque document, un succès ou une erreur (conflict) : vérifier chaque élément, le code HTTP global est 201 même si certains documents échouent.

Fenêtre de terminal
curl -sn "$COUCH/boutique/_all_docs?include_docs=true&limit=10" | jq '.rows[].doc'
curl -sn "$COUCH/boutique/_all_docs?startkey=\"client-\"&endkey=\"client-￰\"&include_docs=true" | jq '.rows | length'
curl -sn -X POST "$COUCH/boutique/_all_docs?include_docs=true" \
-H 'Content-Type: application/json' -d '{"keys":["client-2","client-3"]}' | jq .

L’intervalle startkey / endkey avec ￰ sélectionne tous les identifiants qui commencent par un préfixe.

Fenêtre de terminal
curl -sn -X PUT "$COUCH/boutique/client-2/photo.jpg?rev=1-…" \
-H 'Content-Type: image/jpeg' --data-binary @photo.jpg
curl -sn "$COUCH/boutique/client-2/photo.jpg" -o recuperee.jpg

Les pièces jointes sont stockées dans le document. Pour de gros fichiers, préférer un stockage de fichiers séparé et ne conserver que la référence.

Principe Explication
Pas de jointures Dupliquer les données lues ensemble, ou lier par identifiant et lire en deux requêtes
Un document = une unité de lecture Regrouper ce qui est lu ensemble (commande et lignes)
Documents de taille raisonnable Quelques Ko : limite par défaut de 8 Mo (max_document_size)
Champ type Distinguer les familles dans une même base
Identifiants préfixés commande:2026-0042 permet des plages avec _all_docs

Exemple de commande avec ses lignes :

{
"_id": "commande:2026-0042",
"type": "commande",
"client": "client-2",
"lignes": [
{ "article": "A12", "quantite": 2, "prix": 9.9 },
{ "article": "B07", "quantite": 1, "prix": 24.0 }
],
"statut": "nouvelle"
}

Un document dont l’identifiant commence par _design/ contient des vues, des index ou des validations (voir Index et performances) :

Fenêtre de terminal
curl -sn "$COUCH/boutique/_design/clients" | jq .
Fenêtre de terminal
curl -sn "$COUCH/boutique/client-2?revs_info=true" | jq ._revs_info
curl -sn "$COUCH/boutique/client-2?rev=1-…" | jq .

Les anciennes révisions ne sont conservées que jusqu’à la compaction : ne pas les utiliser comme historique métier (voir Sauvegarde et réplication).

Symptôme Piste
409 conflict _rev périmé : relire le document
{"error":"file_exists"} La base existe déjà (PUT d’une base existante)
{"error":"illegal_database_name"} Nom invalide (majuscules, caractère interdit)
{"error":"doc_validation"} Fonction de validation d’un document de conception
{"error":"document_too_large"} Document supérieur à max_document_size
{"error":"bad_request","reason":"Invalid rev format"} Format de révision incorrect
Un champ a disparu après un PUT Mise à jour par remplacement : renvoyer tous les champs

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune : le comportement dépend de la version de CouchDB.