Comment accéder à une collection préexistante avec Mongoose?

139

J'ai une grande collection de 300 questionobjets dans une base de données test. Je peux facilement interagir avec cette collection grâce au shell interactif de MongoDB; cependant, lorsque j'essaie d'obtenir la collection via Mongoose dans une application express.js, j'obtiens un tableau vide.

Ma question est la suivante: comment puis-je accéder à cet ensemble de données déjà existant au lieu de le recréer en express? Voici un code:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');
mongoose.model('question', new Schema({ url: String, text: String, id: Number }));

var questions = mongoose.model('question');
questions.find({}, function(err, data) { console.log(err, data, data.length); });

Cela produit:

null [] 0
theabraham
la source

Réponses:

252

Mongoose a ajouté la possibilité de spécifier le nom de la collection sous le schéma, ou comme troisième argument lors de la déclaration du modèle. Sinon, il utilisera la version plurielle donnée par le nom que vous mappez au modèle.

Essayez quelque chose comme ce qui suit, soit mappé sur le schéma:

new Schema({ url: String, text: String, id: Number}, 
           { collection : 'question' });   // collection name

ou modèle mappé:

mongoose.model('Question', 
               new Schema({ url: String, text: String, id: Number}), 
               'question');     // collection name
calvinfo
la source
9
Où puis-je trouver ces informations dans la documentation? Cela a vraiment aidé mais il n'y a pas de place pour expliquer le pluriel.
StudioWorks
Salut, @calvinfo comment puis-je changer le nom de la collection lors de l'exécution? J'ai 5 collections de UserSchema et je veux donner à chacun un nom différent Par exemple: users_server1, users_server2, users_server3 ...
Ragnar
1
Veuillez fournir un exemple de requête, par exemple avecModel.collection.insert();..
Steve K
6
Même ici, je passe de nombreuses heures sur cette question figurant, le document se trouve ici mongoosejs.com/docs/guide.html#collection
Elvind
3
Cela a fonctionné pour moi. J'avais une collection d'utilisateurs que je mongorestore. Pour y accéder avec mangouste, j'ai faitmongoose.connect("mongodb://localhost/fromlab"); var Schema = mongoose.Schema; var User = mongoose.model("User", new Schema({}), "users"); User.find({}, function(err, doc){ console.log((doc)) })
jack blank
62

Voici une abstraction de la réponse de Will Nathan si quelqu'un veut juste une fonction complémentaire simple de copier-coller:

function find (name, query, cb) {
    mongoose.connection.db.collection(name, function (err, collection) {
       collection.find(query).toArray(cb);
   });
}

faites simplement find(collection_name, query, callback);pour obtenir le résultat.

par exemple, si j'ai un document {a: 1} dans une collection 'foo' et que je veux lister ses propriétés, je fais ceci:

find('foo', {a : 1}, function (err, docs) {
            console.dir(docs);
        });
//output: [ { _id: 4e22118fb83406f66a159da5, a: 1 } ]
Michael Taufen
la source
Ceci est très utile lors de l'exécution de tests d'intégration sur une API
Greg
salut, est-ce une opération atomique? Supposons que j'essaie ensuite d'enregistrer le document dans la fonction de rappel. ce sera atomique?
Maulik Soneji
23

Vous pouvez faire quelque chose comme ça, puis vous accéderez aux fonctions natives de mongodb à l'intérieur de mongoose:

var mongoose = require("mongoose");
mongoose.connect('mongodb://localhost/local');

var connection = mongoose.connection;

connection.on('error', console.error.bind(console, 'connection error:'));
connection.once('open', function () {

    connection.db.collection("YourCollectionName", function(err, collection){
        collection.find({}).toArray(function(err, data){
            console.log(data); // it will print your collection data
        })
    });

});
Leo Ribeiro
la source
1
Réponse parfaite!
CandleCoder
15

J'ai eu le même problème et j'ai pu exécuter une requête sans schéma en utilisant une connexion Mongoose existante avec le code ci-dessous. J'ai ajouté une simple contrainte 'a = b' pour montrer où vous ajouteriez une telle contrainte:

var action = function (err, collection) {
    // Locate all the entries using find
    collection.find({'a':'b'}).toArray(function(err, results) {
        /* whatever you want to do with the results in node such as the following
             res.render('home', {
                 'title': 'MyTitle',
                 'data': results
             });
        */
    });
};

mongoose.connection.db.collection('question', action);
Will Nathan
la source
1
C'est exactement ce que je recherchais car mongoose n'a pas de support gridFS. J'utilise cette méthode pour récupérer les métadonnées de fichier de gridfs (gridstore). Remplacez simplement questionle code ci-dessus par fs.fileset vous êtes prêt à partir.
k00k
7

Êtes-vous sûr de vous être connecté à la base de données? (Je demande parce que je ne vois pas de port spécifié)

essayer:

mongoose.connection.on("open", function(){
  console.log("mongodb is connected!!");
});

En outre, vous pouvez faire un "show collections" dans mongo shell pour voir les collections dans votre db - peut-être essayer d'ajouter un enregistrement via mangouste et voir où il se termine?

De l'apparence de votre chaîne de connexion, vous devriez voir l'enregistrement dans la base de données "test".

J'espère que ça aide!

bustiqué
la source
4
Intéressant, c'est en fait le stockage des informations dans une questionscollection lorsque les données auxquelles j'essaie d'accéder se trouvent dans une questioncollection. Mongoose met-il automatiquement au pluriel les noms de collection / modèle?
theabraham
Ouais je pense que oui ... ha! Je ne fais que commencer moi-même, donc je n'ai pas exploré tous les coins et recoins ... mais je me souviens avoir vu cette petite brise de châtaigne passer alors que je parcourais les groupes Google.
Busticated le
3

Une autre chose qui n'était pas évidente, du moins pour moi, était que lorsque vous utilisez le troisième paramètre de Mongoose pour éviter de remplacer la collection réelle par une nouvelle avec le même nom, le new Schema(...)n'est en fait qu'un espace réservé et n'interfère pas avec l'exisitng schéma donc

var User = mongoose.model('User', new Schema({ url: String, text: String, id: Number}, { collection : 'users' }));   // collection name;
User.find({}, function(err, data) { console.log(err, data, data.length);});

fonctionne correctement et renvoie tous les champs, même si le schéma réel (distant) ne contient aucun de ces champs. Mongoose le voudra toujours comme new Schema(...), et une variable ne le piratera presque certainement pas.

Bart
la source
1
cela me donne une erreur «le nom de la collection doit être une chaîne», Edit: comme réponse de «calvinfo», si vous voulez donner le nom de la collection dans le constructeur de modèle, vous passez simplement le nom de la collection sous forme de chaîne et non de modèle objet. donc votre réponse sera vraie si éditez comme ceci, var User = mongoose.model ('User', new Schema ({url: String, text: String, id: Number}, 'users')); // nom de la collection; User.find ({}, function (err, data) {console.log (err, data, data.length);});
Kaan Erkoç