MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Obtenir l'index d'un élément dans la requête mongodb

Classement par ID de sujet

Si votre subjectID est (ou peut être changé en) une valeur croissante de manière monotone (par exemple, un ObjectID par défaut de MongoDB), vous avez une option simple en utilisant un find() normal avec le tri, le saut et la limite appropriés. Dans ce cas, vous pouvez rechercher des documents avec des ID de sujet $gte (supérieur ou égal à) votre subjectID :

var page = 1;
var subjectID = ObjectId("515535a0760fe8735f5f6897");
db.users.find(
    { _id: { $gte : subjectID } }
).sort({'_id':1}).skip(page*20).limit(20)

Cadre d'agrégation

Comme dans MongoDb 2.4, il n'existe aucune fonctionnalité de ce type dans le cadre d'agrégation à faire correspondre en fonction de la position du document dans le pipeline de résultats. Vous pouvez déposer une nouvelle suggestion de fonctionnalité sur le SERVER du projet MongoDB Jira. file d'attente.

Il semble que vous souhaitiez un nouvel opérateur de pipeline tel qu'un $matchfrom qui ignorerait tous les documents jusqu'à la première occurrence de $matchfrom Critères. Vous pouvez ensuite ajouter un $limit pour prendre les n éléments suivants. Vous voudriez également avoir une sortie triée avant le $matchfrom il y a donc un résultat prévisible.

Cela semble trop compliqué par rapport à l'augmentation du subjectID, mais il peut y avoir un cas d'utilisation pour effectuer une pagination basée sur des critères de recherche plus avancés ou des résultats calculés dans le pipeline d'agrégation.

Approches alternatives

Outre la prise en charge future d'une telle fonctionnalité dans le cadre d'agrégation, vous disposez de quelques options pour implémenter la même approche de correspondance dans le code :

  • utilisez l'ancien group() commande d'agrégation avec un finalize() fonction. REMARQUE :group() n'est pas travailler avec des clusters partitionnés.

  • utilisez MapReduce et un finalize() fonction

  • récupérez l'ensemble des résultats à partir du cadre d'agrégation et implémentez la correspondance/réduction des résultats dans votre code d'application (bien que cela va quelque peu à l'encontre de la notion de "pagination" si vous récupérez toutes les pages pour chaque requête).

Considérations relatives aux performances

Requêtes avec skip devez toujours lire les entrées d'index intermédiaires, donc ignorer un grand nombre de documents ne sera pas très efficace.

Au lieu de paginer avec un décalage de saut, vous pouvez envisager de faire des requêtes de page successives en commençant par la dernière entrée de la page précédente (c'est-à-dire que la première page serait $gte le subjectID de départ et les pages suivantes seraient $gt le dernier subjectID inclus sur la page précédente). Cela dépendra de la façon dont vous présentez la pagination dans votre interface utilisateur - il serait plus facile d'utiliser cette approche si votre interface utilisateur n'a que la possibilité d'afficher la page "suivante" de messages plutôt que de sauter à une page spécifique.