Obtention des modifications des documents dans la base de données

Envoi d'une demande GET à https://$ACCOUNT.cloudant.com/$DATABASE/_changes renvoie une liste des modifications apportées aux documents de la base de données, y compris les insertions, les mises à jour et les suppressions.

Lorsqu'une demande _changes est reçue, une réplique pour chaque fragment de la base de données doit fournir une liste de modifications. Ces réponses sont combinées et renvoyées au client à l'origine de la demande.

Le noeud final _changes accepte plusieurs arguments de requête facultatifs :

Arguments de requête du noeud final _changes
Argument Description Valeurs prises en charge Valeur par défaut
conflicts Ne peut être défini que si include_docs a pour valeur true. Ajoute des informations sur les conflits dans chaque document. Booléen Faux
descending Renvoie les modifications dans l'ordre séquentiel. Booléen Faux
doc_ids A utiliser uniquement si filter a pour valeur _doc_ids. Filtre le flux pour que seules les modifications apportées aux documents spécifiés soient envoyées. Remarque : le paramètre doc_ids fonctionne uniquement avec les versions d'IBM Cloudant qui sont compatibles avec CouchDB 2.0. Pour plus d'informations, consultez GET / la documentation. Tableau JSON d'ID de document
feed Type de flux requis. Pour plus d'informations, voir les informations feed. "continuous", "longpoll", "normal" "normal"
filter Nom de la fonction de filtrage à utiliser pour obtenir les mises à jour. Le filtre est défini dans un document de conception. string Pas de filtre
heartbeat Si aucune modification n'a été apportée pendant la période définie par feed=longpoll ou feed=continuous, une ligne vide est envoyée à la fin de la période exprimée en millisecondes. Tout nombre positif Pas de signal de présence
include_docs Inclut le document dans le résultat. Booléen Faux
limit Nombre maximal de lignes à renvoyer. Tout nombre non négatif Aucun
seq_interval Indique à quelle fréquence la valeur seq est incluse dans la réponse. Définissez une valeur supérieure pour augmenter le débit de _changes et réduire la taille de la réponse. Remarque : en mode _changes non continu, la valeur last_seq est toujours renseignée. Tout nombre positif 1
since Démarre les résultats provenant des modifications après l'identificateur de séquence spécifié. Pour plus d'informations, voir les informations since. Identificateur de séquence ou now 0
style Spécifie le nombre de révisions qui sont renvoyées dans le tableau des modifications. Le style main_only renvoie uniquement la révision "gagnante" en cours. Le style all_docs renvoie toutes les révisions feuilles, y compris les conflits et les anciens conflits supprimés. main_only, all_docs main_only
timeout Attend des données pendant cette durée spécifiée en millisecondes, puis arrête la réponse. Si le paramètre heartbeat est également fourni, il a priorité sur le paramètre timeout. Tout nombre positif

L'utilisation d'include_docs=true peut avoir une incidence sur les performances.

Voici un exemple qui utilise HTTP pour obtenir la liste des modifications apportées aux documents d'une base de données :

GET /$DATABASE/_changes HTTP/1.1

Voir l'exemple suivant pour obtenir une liste des modifications apportées aux documents dans une base de données :

curl -H "Authorization: Bearer $API_BEARER_TOKEN" -X GET "$SERVICE_URL/orders/_changes?limit=1"

Modifications dans une base de données répartie

Les bases de données IBM Cloudant sont réparties. Elles présentent des caractéristiques de fragment et de tolérance aux pannes. Ainsi, les réponses fournies par la demande _changes peuvent être différentes du comportement que vous prévoyez.

En particulier, si vous demandez une liste de modifications à partir d'un identificateur de séquence avec le paramètre _since, vous obtenez les informations demandées en réponse. Mais vous pouvez également obtenir des modifications qui ont été effectuées avant la modification indiquée par l'identificateur de séquence. La raison pour laquelle ces modifications supplémentaires sont incluses ainsi que les implications pour les applications sont expliquées dans le guide de réplication.

Toute application qui utilise la demande _changes doit pouvoir traiter correctement une liste de modifications, comme indiqué dans la liste suivante :

  • Un ordre différent pour les modifications qui sont répertoriées dans la réponse, par rapport à une demande précédente concernant les mêmes informations.
  • Des modifications qui ont été effectuées avant la modification spécifiée par l'identificateur de séquence.

L'argument feed

L'argument feed change la façon dont IBM Cloudant envoie la réponse. Par défaut, _changes signale toutes les modifications, puis la connexion est fermée. Ce comportement est le même qu'avec l'argument feed=normal.

Si vous définissez feed=longpoll, les demandes envoyées au serveur restent ouvertes jusqu'à ce que des modifications soient rapportées. Cette option est utile lors de la surveillance en continu des modifications.

Si vous définissez feed=continuous, les nouvelles modifications sont signalées au fur et à mesure qu'elles se produisent. Cette option signifie que la connexion à la base de données reste ouverte pendant un certain temps. La réponse peut se terminer à tout moment et les clients doivent se reconnecter s'ils souhaitent continuer à recevoir des modifications.

Chaque ligne dans la réponse continue est vide ou contient un objet JSON qui représente une modification unique. Cette option garantit le respect des instructions suivantes :

  • Le format des entrées de rapport reflète la nature continue des modifications.
  • La validité de la sortie JSON est maintenue.

Voici des exemples de réponse (abrégée) pour un flux de modifications continues :

{
	"seq": "1-g1A...qyw",
	"id": "2documentation22d01513-c30f-417b-8c27-56b3c0de12ac",
	"changes": [
		{
			"rev": "1-967a00dff5e02add41819138abb3284d"
		}
	]
},
{
	"seq": "2-g1A...ssQ",
	"id": "1documentation22d01513-c30f-417b-8c27-56b3c0de12ac",
	"changes": [
		{
			"rev": "1-967a00dff5e02add41819138abb3284d"
		}
	]
},
{
	"seq": "3-g1A...qyy",
	"id": "1documentation22d01513-c30f-417b-8c27-56b3c0de12ac",
	"changes": [
		{
			"rev": "2-eec205a9d413992850a6e32678485900"
		}
	],
	"deleted": true
},
{
	"seq": "4-g1A...qyz",
	"id": "2documentation22d01513-c30f-417b-8c27-56b3c0de12ac",
	"changes": [
		{
			"rev": "2-eec205a9d413992850a6e32678485900"
		}
	],
	"deleted": true
}

L'argument filter

L'argument filter désigne une fonction de filtrage prédéfinie à appliquer au flux de modifications. De plus, plusieurs filtres intégrés sont disponibles :

_design

Le filtre « _design » n'accepte que les modifications apportées aux documents de conception.

_doc_ids

Ce filtre n'accepte que les modifications apportées aux documents dont l'ID est spécifié dans le paramètre « doc_ids ».

_selector

Renvoie les modifications apportées aux documents correspondant au paramètre « selector » du corps de la requête. La syntaxe de sélecteur est identique à la syntaxe utilisée pour _find. Si vous souhaitez utiliser un filtre de sélection, vous devez utiliser le flux des modifications « POST » (car il n'est pas possible de fournir un corps de document avec une requête GET). Utilisez la méthode de filtrage « _selector » plutôt que la méthode « _view », car elle est plus rapide et plus simple à utiliser.

Pour plus d'informations, voir la documentation de l'API.

_view

Active l'utilisation d'une fonction de mappe existante comme filtre.

L'argument since

Utilisez l'argument since pour obtenir la liste des modifications qui ont été effectuées après un identificateur de séquence spécifié. Si l'identificateur since est 0 (valeur par défaut) ou est omis, la demande renvoie toutes les modifications. Si l'identificateur since est now, la demande requiert les modifications qui ont été effectuées après l'heure en cours.

L'aspect "réparti" d'IBM Cloudant peut avoir un impact sur les résultats que vous obtenez dans une réponse. Par exemple, si vous demandez une liste de modifications deux fois en utilisant le même identificateur de séquence since, l'ordre des modifications dans la liste générée ne sera pas forcément le même.

Certains résultats peuvent également se situer avant la valeur du paramètre since. En effet, vous pouvez obtenir des résultats provenant d'une réplication de fragment différente.

Les répliques de fragment sont répliquées automatiquement et en continu les unes sur les autres et finissent pas comporter les mêmes données. Cependant, à un moment donné, une réplique de fragment peut être différente d'une autre réplique de fragment si la réplication entre les deux répliques n'est pas terminée.

En général, lorsque vous demandez une liste de modifications, les répliques sont utilisées pour répondre. Toutefois, si le noeud qui contient la réplique de fragment n'est pas disponible, le système procède à son remplacement par une réplique de fragment correspondante se trouvant sur un autre noeud. Pour garantir que toutes les modifications applicables sont affichées, le point de contrôle le plus récent entre les répliques est utilisé. L'utilisation du point de contrôle "restaure" la liste des modifications qui existait au moment le plus récent où les répliques de fragment correspondaient. Avec cette "restauration", il se peut que des modifications effectuées "avant" l'identificateur de séquence since que vous avez fourni soient affichées.

Votre application doit pouvoir traiter une modification qui est rapportée plusieurs fois si vous émettez une demande _changes plusieurs fois.

Pour plus d'informations sur le comportement de la réponse _changes, voir le guide de réplication.

Réponses de la demande _changes

La réponse à une demande _changes est un objet JSON contenant la liste des modifications qui ont été apportées aux documents se trouvant dans la base de données. Le tableau suivant décrit la signification des zones individuelles :

Zones de réponse d'objet JSON pour _changes
Zone Description Type
changes Tableau répertoriant les modifications apportées au document spécifique. Tableau
deleted Valeur booléenne indiquant si le document correspondant a été supprimé. S'il est présent, il possède toujours la valeur true. Booléen
id Identificateur du document. Chaîne
last_seq Dernier identificateur de séquence. Actuellement, cet identificateur est identique à l'identificateur de séquence du dernier élément dans les results. Chaîne
results Tableau des modifications apportées à la base de données. Tableau
seq Mise à jour de l'identificateur de séquence. Chaîne

Voici un exemple de réponse (abrégée) à une demande _changes :

{
	"results": [
		{
			"seq": "1-g1A...sIg",
			"id": "foo",
			"changes": [
				{
					"rev": "1-967...84d"
				}
			]
		}
	],
	"last_seq": "1-g1A...sIg",
	"pending": 0
}

Remarques importantes sur _changes

  • Les résultats renvoyés par _changes sont partiellement ordonnés. En d'autres termes, il se peut que l'ordre ne soit pas préservé pour plusieurs appels. Vous pouvez choisir d'obtenir une liste en cours avec _changes en incluant la valeur last_seq. La liste obtenue fournit le point de départ des listes _changes suivantes qui utilisent l'argument de requête since.
  • Bien que les copies de fragment de la même plage contiennent les mêmes données, leur historique _changes est souvent unique. Cette différence résulte de la façon dont les écritures sont appliquées au fragment. Par exemple, elles peuvent être appliquées dans un ordre différent. Pour vous assurer que toutes les modifications sont rapportées pour la séquence que vous avez spécifiée, il peut être nécessaire de revenir plus loin en arrière dans l'historique du fragment pour trouver un point de départ adapté. Les modifications sont alors rapportées depuis ce point de départ. Ce "retour en arrière" peut donner l'impression que des mises à jour sont en double ou se situent apparemment avant la valeur since spécifiée.
  • Les modifications _changes rapportées par un fragment sont toujours présentées dans l'ordre. Toutefois, l'ordre sur les divers fragments de contribution peut être différent. Pour plus d'informations, consultez l'exemple « A Changes Feed ».
  • Les valeurs de séquence sont uniques pour un fragment, mais peuvent varier selon le fragment. Cette variation signifie que si vous disposez de valeurs de séquence provenant de différents fragments, vous ne pouvez pas supposer que la même valeur de séquence référence le même document dans différents fragments.

Utilisation de POST pour obtenir des modifications

Au lieu de GET, vous pouvez aussi utiliser POST pour interroger le flux de modifications. La seule différence, si vous utilisez POST et que vous utilisez l'un des filtres docs_ids ou selector, est qu'il est possible d'inclure les composants "doc_ids" : [...] ou "selector": {...} dans le corps de la demande. Tous les autres paramètres doivent se trouver dans la chaîne de requête, comme pour GET.

Voici un exemple qui utilise HTTP pour envoyer une demande POST au noeud final _changes :

POST /$DATABASE/_changes?filter=_selector HTTP/1.1
Host: $ACCOUNT.cloudant.com
Content-Type: application/json

Reportez-vous à l'exemple suivant pour POST sur le nœud final _changes :

curl -H "Authorization: Bearer $API_BEARER_TOKEN" -X POST "$SERVICE_URL/orders/_changes" -H "Content-Type: application/json"'
import com.ibm.cloud.cloudant.v1.Cloudant;
import com.ibm.cloud.cloudant.v1.model.ChangesResult;
import com.ibm.cloud.cloudant.v1.model.PostChangesOptions;
Cloudant service = Cloudant.newInstance();
PostChangesOptions changesOptions = new PostChangesOptions.Builder()
    .db("orders")
    .build();
ChangesResult response =
    service.postChanges(changesOptions).execute()
        .getResult();
System.out.println(response);
import { CloudantV1 } from '@ibm-cloud/cloudant';
const service = CloudantV1.newInstance({});
service.postChanges({
  db: 'orders'
}).then(response => {
  console.log(response.result);
});
from ibmcloudant.cloudant_v1 import CloudantV1
service = CloudantV1.new_instance()
response = service.post_changes(
  db='orders'
).get_result()
print(response)
postChangesOptions := service.NewPostChangesOptions(
  "orders",
)
changesResult, response, err := service.PostChanges(postChangesOptions)
if err != nil {
  panic(err)
}
b, _ := json.MarshalIndent(changesResult, "", "  ")
fmt.Println(string(b))

L'exemple précédent de Go requiert le bloc d'importation suivant :

import (
   "encoding/json"
   "fmt"
   "github.com/IBM/cloudant-go-sdk/cloudantv1"
)

Tous les exemples de Go nécessitent l'initialisation de l'objet service. Pour plus d'informations, reportez-vous à la documentation de l'API Section Authentification pour avoir des exemples.

Lorsque vous effectuez une demande POST sur le noeud final _changes, un objet JSON similaire au suivant est reçu :

{"results":[
{"seq":"1-g1AAAA...","id":"0007741142412418284","changes":[{"rev":"1-9d0c2676941ec3a3b3cc2f08fe9a51e0"}]},
{"seq":"2-g1AAAA...","id":"_design/applianceId","changes":[{"rev":"1-b1f67a8b672c1324680d6d7dc1e1fd3c"}]},
...
],
"last_seq":"18-g1AAAA...","pending":0}

Pagination

Utilisez le paramètre since comme un signet pour paginer le flux de modifications. Pour plus de détails et d'exemples, voir la rubrique de la documentation de l'API consacrée à la pagination du flux de modifications.