web-dev-qa-db-fra.com

Comment obtenir les derniers N enregistrements à Mongodb?

Je ne trouve nulle part où cela a été documenté. Par défaut, l'opération find () obtiendra les enregistrements à partir du début. Comment puis-je obtenir les N derniers enregistrements dans mongodb?

Edit: je souhaite également que le résultat renvoyé soit ordonné du moins récent au plus récent, et non l'inverse.

425
Bin Chen

Si je comprends votre question, vous devez trier par ordre croissant.

En supposant que vous ayez un identifiant ou un champ de date appelé "x", vous le feriez ...

.Trier()


db.foo.find().sort({x:1});

1 triera par ordre croissant (du plus ancien au plus récent) et -1 triera par ordre décroissant (du plus récent au plus ancien).

Si vous utilisez le champ _id créé automatiquement, une date y est intégrée ... vous pouvez donc l'utiliser pour passer commande par ...

db.foo.find().sort({_id:1});

Cela renverra tous vos documents triés du plus ancien au plus récent.

Ordre naturel


Vous pouvez également utiliser un Ordre Naturel mentionné ci-dessus ...

db.foo.find().sort({$natural:1});

Encore une fois, utilisez 1 ou -1 en fonction de l'ordre souhaité.

Utilisez .limit ()


Enfin, il est judicieux d’ajouter une limite lorsque vous effectuez ce type de requête ouverte afin que vous puissiez le faire ...

db.foo.find().sort({_id:1}).limit(50);

ou

db.foo.find().sort({$natural:1}).limit(50);
605
Justin Jenkins

Les derniers N enregistrements ajoutés, du moins récent au plus récent, peuvent être vus avec cette requête:

db.collection.find().skip(db.collection.count() - N)

Si vous les voulez dans l'ordre inverse:

db.collection.find().sort({ $natural: -1 }).limit(N)

Si vous installez Mongo-Hacker vous pouvez également utiliser:

db.collection.find().reverse().limit(N)

Si vous en avez assez d'écrire ces commandes tout le temps, vous pouvez créer des fonctions personnalisées dans votre ~/.mongorc.js. Par exemple.

function last(N) {
    return db.collection.find().skip(db.collection.count() - N);
}

puis, à partir d'un shell mongo, tapez simplement last(N)

95

Pour obtenir les N derniers enregistrements, vous pouvez exécuter la requête ci-dessous:

db.yourcollectionname.find({$query: {}, $orderby: {$natural : -1}}).limit(yournumber)

si vous ne voulez qu'un dernier enregistrement:

db.yourcollectionname.findOne({$query: {}, $orderby: {$natural : -1}})

Remarque: au lieu de $ naturel, vous pouvez utiliser l’une des colonnes de votre collection.

13
Ashwini

vous pouvez utiliser sort(), limit(), skip() pour obtenir le dernier enregistrement N à partir de toute valeur ignorée 

db.collections.find().sort(key:value).limit(int value).skip(some int value);
6
pkp

Regardez sous Interrogation: tri et ordre naturel, http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order Ainsi que sort () sous Méthodes de curseur . http://www.mongodb.org/display/DOCS/Advanced+Queries

5
Steve Wilhelm

Vous ne pouvez pas "ignorer" en fonction de la taille de la collection, car les conditions de la requête ne seront pas prises en compte.

La solution correcte consiste à trier du point final souhaité, à limiter la taille du jeu de résultats, puis à ajuster l'ordre des résultats si nécessaire. 

Voici un exemple basé sur du code du monde réel.

var query = collection.find( { conditions } ).sort({$natural : -1}).limit(N);

query.exec(function(err, results) {
    if (err) { 
    }
    else if (results.length == 0) {
    }
    else {
        results.reverse(); // put the results into the desired order
        results.forEach(function(result) {
            // do something with each result
        });
    }
});
5
Marty Hirsch

@ bin-chen,

Vous pouvez utiliser une agrégation pour les n dernières entrées d'un sous-ensemble de documents dans une collection. Voici un exemple simplifié sans regroupement (ce que vous feriez entre les étapes 4 et 5 dans ce cas).

Cela renvoie les 20 dernières entrées (basées sur un champ appelé "horodatage"), triées par ordre croissant. Il projette ensuite chaque document id, timestamp et any_field_you_want_to_show dans les résultats.

var pipeline = [
        {
            "$match": { //stage 1: filter out a subset
                "first_field": "needs to have this value",
                "second_field": "needs to be this"
            }
        },
        {
            "$sort": { //stage 2: sort the remainder last-first
                "timestamp": -1
            }
        },
        {
            "$limit": 20 //stage 3: keep only 20 of the descending order subset
        },
        {
            "$sort": {
                "rt": 1 //stage 4: sort back to ascending order
            }
        },
        {
            "$project": { //stage 5: add any fields you want to show in your results
                "_id": 1,
                "timestamp" : 1,
                "whatever_field_you_want_to_show": 1
            }
        }
    ]

yourcollection.aggregate(pipeline, function resultCallBack(err, result) {
  // account for (err)
  // do something with (result)
}

alors, le résultat ressemblerait à quelque chose comme:

{ 
    "_id" : ObjectId("5ac5b878a1deg18asdafb060"),
    "timestamp" : "2018-04-05T05:47:37.045Z",
    "whatever_field_you_want_to_show" : -3.46000003814697
}
{ 
    "_id" : ObjectId("5ac5b878a1de1adsweafb05f"),
    "timestamp" : "2018-04-05T05:47:38.187Z",
    "whatever_field_you_want_to_show" : -4.13000011444092
}

J'espère que cela t'aides.

2
lauri108

Vous voudrez peut-être utiliser les options find: http://docs.meteor.com/api/collections.html#Mongo-Collection-find

db.collection.find({}, {sort: {createdAt: -1}, skip:2, limit: 18}).fetch();
2
Lucbug

Vous pouvez essayer cette méthode:

Obtenez le nombre total d'enregistrements de la collection avec 

db.dbcollection.count() 

Puis utilisez skip:

db.dbcollection.find().skip(db.dbcollection.count() - 1).pretty()
1
bello hargbola

utilisez $ slice operator pour limiter les éléments du tableau 

GeoLocation.find({},{name: 1, geolocation:{$slice: -5}})
    .then((result) => {
      res.json(result);
    })
    .catch((err) => {
      res.status(500).json({ success: false, msg: `Something went wrong. ${err}` });
});

où la géolocalisation est un tableau de données, à partir de là nous obtenons 5 derniers enregistrements 

0
KARTHIKEYAN.A

Le tri, le saut, etc. peuvent être assez lents en fonction de la taille de votre collection.

Une meilleure performance serait obtenue si votre collection était indexée selon certains critères; et alors vous pourriez utiliser le curseur min ():

Tout d’abord, indexez votre collection avec db.collectionName.setIndex( yourIndex )Vous pouvez utiliser un ordre croissant ou décroissant, ce qui est bien, car vous voulez toujours les "N derniers éléments" ... donc si vous indexez par ordre décroissant, vous obtenez le " premiers N éléments ".

Ensuite, vous trouvez le premier élément de votre collection et utilisez ses valeurs de champ d’index comme critère minimal dans une recherche comme celle-ci:

db.collectionName.find().min(minCriteria).hint(yourIndex).limit(N)

Voici la référence pour le curseur min (): https://docs.mongodb.com/manual/reference/method/cursor.min/

0
João Otero
db.collection.find().hint( { $natural : -1 } ).sort(field: 1/-1).limit(n)

selon Documentation mongoDB :

Vous pouvez spécifier {$ natural: 1} pour forcer la requête à effectuer une analyse de collecte avant.

Vous pouvez également spécifier {$ natural: -1} pour forcer la requête à effectuer une analyse de collecte inverse.

0
Gili.il