Comment fonctionne le jeton de continuation Cosmos DB?
À première vue, ce que fait le jeton de continuation dans Cosmos DB est clair: l'attacher à la requête suivante vous donne le prochain ensemble de résultats. Mais que signifie exactement «prochain ensemble de résultats»?
Est-ce que ça veut dire que:
- l'ensemble suivant de résultats comme si la requête d'origine avait été exécutée complètement sans pagination au moment de la toute première requête (sautant le nombre approprié de documents)?
- le prochain ensemble de résultats comme si la requête d'origine avait été exécutée maintenant (en sautant le nombre approprié de documents)?
- Quelque chose de complètement différent?
La réponse 1. semblerait préférable mais peu probable étant donné que le serveur aurait besoin de stocker des quantités illimitées d'état. Mais la réponse 2 est également problématique car elle peut entraîner des incohérences, par exemple le même document peut être servi plusieurs fois sur plusieurs pages, si les données sous-jacentes ont changé entre les requêtes de page.
Réponses
Les exécutions de requêtes Cosmos DB sont sans état du côté serveur. Le jeton de continuation est utilisé pour recréer l'état de l'index et suivre la progression de l'exécution.
«Ensemble de résultats suivant» signifie que la requête est à nouveau exécutée à partir d'un «signet» de l'exécution précédente. Ce signet est fourni par le jeton de continuation.
- Documents créés lors des suites
Ils peuvent ou non être retournés en fonction de la position de l'insertion et de la requête en cours d'exécution.
Exemple:
SELECT * FROM c ORDER BY c.someValue ASC
Supposons que le signet ait someValue = 10, le moteur de requête reprend le traitement en utilisant un jeton de continuation où someValue = 10.
Si vous deviez insérer un nouveau document avec someValue = 5 entre les exécutions de requête, il n'apparaîtra pas dans le prochain ensemble de résultats.
Si le nouveau document est inséré dans une "page" qui est> le signet, il apparaîtra dans le prochain ensemble de résultats
- Documents mis à jour lors des suites
La même logique que ci-dessus s'applique également aux mises à jour (voir # 4)
- Documents supprimés lors des suites
Ils n'apparaîtront pas dans la prochaine série de résultats.
- Risques de doublons
Dans le cas de la requête ci-dessous,
SELECT * FROM c ORDER BY c.remainingInventory ASC
Si l'inventaire restant a été mis à jour après le premier ensemble de résultats et qu'il satisfait désormais aux critères ORDER BY pour la deuxième page, le document s'affiche à nouveau.
Cosmos DB ne fournit pas d'isolation de cliché sur les pages de requête. Cependant, selon l'équipe produit, il s'agit d'un scénario incroyablement rare car les requêtes sur les continuations sont très rapides et dans la plupart des cas, tous les résultats des requêtes sont renvoyés sur la première page.
Sur la base d'expériences préliminaires, la réponse semble être l'option n ° 2, ou plus précisément:
- Les documents créés après avoir servi la première page sont visibles sur les pages suivantes
- Les documents mis à jour après avoir servi la première page sont visibles sur les pages suivantes
- Les documents supprimés après avoir servi la première page sont omis sur les pages suivantes
- Les documents ne sont jamais signifiés deux fois
La première déclaration ci-dessus contredit les informations de MSFT ( cf. réponse de Kalyan). Ce serait formidable d'obtenir une réponse plus nuancée de la part de l'équipe Cosmos DB spécifiant précisément la sémantique de la récupération des pages. Cela peut ne pas être très important pour afficher les données dans l'interface utilisateur, mais peut être essentiel pour le traitement des données dans le backend, étant donné qu'il ne semble pas y avoir de moyen de désactiver la pagination lors de l'exécution d'une requête ( cf. Les requêtes transactionnelles sont-elles possibles dans Cosmos DB? ).
Méthode expérimentale
J'ai utilisé Cosmos DB Explorer de Sacha Bruttin pour interroger une collection de 5 documents, car cet outil permet de jouer avec la taille de la page et d'autres options de requête.
La taille de la page a été définie sur 1 et les requêtes de partition croisée ont été activées. Différentes requêtes ont été essayées, par exemple SELECT * FROM c
ou SELECT * FROM c ORDER BY c.name
.
Après avoir récupéré la page 1, de nouveaux documents ont été insérés et certains documents existants (y compris les documents qui devraient apparaître sur les pages suivantes) ont été mis à jour et supprimés. Ensuite, toutes les pages suivantes ont été récupérées dans l'ordre.
(Un rapide coup d'œil au code source de l'outil a confirmé qu'il ResponseContinuationTokenLimitInKb
n'est pas défini.)