Come accedere a una raccolta preesistente con Mongoose?


139

Ho una grande collezione di 300 question oggetti in un database test. Posso interagire facilmente con questa raccolta tramite la shell interattiva di MongoDB; tuttavia, quando provo a ottenere la raccolta tramite Mongoose in un'applicazione express.js ottengo un array vuoto.

La mia domanda è: come posso accedere a questo set di dati già esistente invece di ricrearlo in Express? Ecco un po 'di codice:

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); });

Questo produce:

null [] 0

Risposte:


252

Mongoose ha aggiunto la possibilità di specificare il nome della raccolta sotto lo schema o come terzo argomento durante la dichiarazione del modello. Altrimenti utilizzerà la versione pluralizzata data dal nome mappato sul modello.

Prova qualcosa di simile al seguente, mappato a schema:

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

o modello mappato:

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

9
Dove nei documenti posso trovare queste informazioni? Questo è davvero aiutato, ma non c'è spazio per spiegare la cosa plurale.
StudioWorks

Ciao, @calvinfo come posso cambiare il nome della collezione in fase di esecuzione? Ho 5 raccolte di UserSchema e voglio dare a ognuna un nome diverso Ad esempio: users_server1, users_server2, users_server3 ...
Ragnar,

1
Per favore, fornisci una query di esempio, ad esempio conModel.collection.insert();..
Steve K,

6
Lo stesso qui, passo molte ore a capire questo problema, il documento si trova qui mongoosejs.com/docs/guide.html#collection
ElvinD

3
Questo ha funzionato per me. Avevo una collezione di utenti che avevo memorizzato. Per accedervi con la mangusta l'ho fattomongoose.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

Ecco un'astrazione della risposta di Will Nathan se qualcuno vuole semplicemente una semplice funzione aggiuntiva di copia-incolla:

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

semplicemente fare find(collection_name, query, callback);per ottenere il risultato.

ad esempio, se ho un documento {a: 1} in una raccolta "pippo" e voglio elencarne le proprietà, lo faccio:

find('foo', {a : 1}, function (err, docs) {
            console.dir(docs);
        });
//output: [ { _id: 4e22118fb83406f66a159da5, a: 1 } ]

Questo è molto utile quando si eseguono test di integrazione su un'API
Greg

ciao, è un'operazione atomica? Supponiamo che provo a salvare il documento nella funzione di richiamata. sarà atomico?
Maulik Soneji

23

Puoi fare qualcosa del genere, di quello che accederai alle funzioni native mongodb all'interno di 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
        })
    });

});

1
Risposta perfetta!
CandleCoder,

15

Ho avuto lo stesso problema ed è stato in grado di eseguire una query senza schema utilizzando una connessione Mongoose esistente con il codice seguente. Ho aggiunto un semplice vincolo 'a = b' per mostrare dove aggiungere un tale vincolo:

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);

1
Questo è esattamente quello che stavo cercando perché la mangusta non ha alcun supporto gridFS. Uso questo metodo per afferrare i metadati dei file da gridfs (gridstore). Basta sostituire questionil codice sopra con fs.filese sei a posto.
k00k,

7

Sei sicuro di esserti collegato al db? (Chiedo perché non vedo una porta specificata)

provare:

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

Inoltre, puoi fare una "mostra collezioni" nella shell mongo per vedere le raccolte nel tuo db - forse provare ad aggiungere un record tramite mongoose e vedere dove finisce?

Dall'aspetto della stringa di connessione, dovresti vedere il record nel db "test".

Spero che sia d'aiuto!


4
Interessante, in realtà sta memorizzando le informazioni in una questionsraccolta quando i dati a cui sto tentando di accedere sono in una questionraccolta. Mongoose pluralizza automaticamente i nomi di collezioni / modelli?
theabraham,

Sì, penso che lo faccia ... ah! Sto iniziando da solo, quindi non ho esplorato tutti gli angoli e le crepe ... ma ricordo di aver visto quella brezza di castagne mentre giravo su Google Gruppi.
Rusticato il

3

Qualcos'altro che non era ovvio, almeno per me, era che quando si utilizzava il terzo parametro di Mongoose per evitare di sostituire la raccolta effettiva con una nuova con lo stesso nome, in new Schema(...)realtà è solo un segnaposto e non interferisce con l'exisitng schema così

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);});

funziona bene e restituisce tutti i campi, anche se lo Schema (remoto) effettivo non contiene nessuno di questi campi. Mongoose lo vorrà ancora comenew Schema(...) , e quasi sicuramente una variabile non lo hackererà.


1
mi dà l'errore "il nome della raccolta deve essere una stringa", Modifica: come risposta di "calvinfo", Se si desidera dare il nome della raccolta nel costruttore del modello, è sufficiente passare il nome della raccolta in forma di stringa e non nel modello a oggetti. quindi la tua risposta sarà vera se modifichi in questo modo, var User = mongoose.model ('User', nuovo schema ({url: String, text: String, id: Number}, 'users')); // nome della raccolta; User.find ({}, function (err, data) {console.log (err, data, data.length);});
Kaan Erkoç,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.