web-dev-qa-db-fra.com

Parcourez toutes les collections Mongo et exécutez la requête

Tout d'abord, je suis assez nouveau pour mongodb. Voici ma question à laquelle je n'ai pas trouvé de solution.

Disons que j'ai 3 collections différentes.

mongos> show collections
collectionA
collectionB
collectionC

Je veux créer un script qui itère sur toutes les collections de cette base de données et trouve le dernier horodatage inséré dans chacune de ces collections. Voici ce qui fonctionne à l'intérieur des mongos.

var last_element = db.collectionA.find().sort({_id:-1}).limit(1);
printjson(last_element.next()._id.getTimestamp());
ISODate("2014-08-28T06:45:47Z")

1. Problème (itérer sur toutes les collections)

Y a-t-il une possibilité de qch. comme.

var my_collections = show collections;
my_collections.forEach(function(current_collection){
    print(current_collection);
});

Problème ici, l'affectation pour my_collections Ne fonctionne pas. J'obtiens SyntaxError: Unexpected identifier. Dois-je citer la déclaration "show"? Est-ce même possible?

2. Problème (stockage de la collection dans js var)

Je peux contourner le problème 1 en procédant comme suit:

var my_collections = ["collectionA", "collectionB", "collectionC"];
my_collections.forEach(function(current_collection){
    var last_element = db.current_collection.find().sort({_id:-1}).limit(1);
    print(current_collection);
    printjson(last_element.next()._id.getTimestamp());
});

La last_element.next() produit l'erreur suivante:

erreur hasNext: false dans src/mongo/Shell/query.js: 124

Il semble que last_element ne soit pas enregistré correctement.

Des suggestions sur ce que je fais mal ??


MISE À JOUR

La réponse de Neils m'a conduit à cette solution. En plus de son code, j'ai dû vérifier si la fonction getTimestamp existe vraiment. Pour certaines collections "virtuelles", il ne semble pas y avoir de propriété _id.

db.getCollectionNames().forEach(function(collname) {
    var last_element = db[collname].find().sort({_id:-1}).limit(1);
    if(last_element.hasNext()){
        var next = last_element.next();
        if(next._id !== undefined && typeof next._id.getTimestamp == 'function'){
           printjson(collname + " >> "+next._id.getTimestamp());
        }else{
          print(collname + " undefined!! (getTimestamp N/A)")
        }
    }
});
21
cb0

Il existe la méthode d'assistance db.getCollectionNames() qui le fait pour vous. Vous pouvez ensuite implémenter votre code:

db.getCollectionNames().forEach(function(collname) {
    // find the last item in a collection
    var last_element = db[collname].find().sort({_id:-1}).limit(1);
    // check that it's not empty
    if (last_element.hasNext()) {
        // print its timestamp
        printjson(last_element.next()._id.getTimestamp());
    }
})

Vous souhaiterez probablement également une .hasNext() archivage pour répondre aux éventuelles collections vides.

43
Neil Lunn