¿Cómo acceder a una colección preexistente con Mongoose?

139

Tengo una gran colección de 300 questionobjetos en una base de datos test. Puedo interactuar fácilmente con esta colección a través del shell interactivo de MongoDB; sin embargo, cuando intento obtener la colección a través de Mongoose en una aplicación express.js obtengo una matriz vacía.

Mi pregunta es, ¿cómo puedo acceder a este conjunto de datos ya existente en lugar de recrearlo en express? Aquí hay un código:

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

Esto produce:

null [] 0
theabraham
fuente

Respuestas:

252

Mongoose agregó la capacidad de especificar el nombre de la colección bajo el esquema, o como el tercer argumento al declarar el modelo. De lo contrario, utilizará la versión pluralizada dada por el nombre que asigna al modelo.

Pruebe algo como lo siguiente, mapeado en esquema:

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

o modelo mapeado:

mongoose.model('Question', 
               new Schema({ url: String, text: String, id: Number}), 
               'question');     // collection name
calvinfo
fuente
9
¿Dónde puedo encontrar esta información en los documentos? Esto realmente ayudó, pero no hay lugar para explicar la cosa plural.
StudioWorks
Hola, @calvinfo, ¿cómo puedo cambiar el nombre de la colección en tiempo de ejecución? Tengo 5 colecciones de UserSchema y quiero darles a cada una un nombre diferente, por ejemplo: users_server1, users_server2, users_server3 ...
Ragnar
1
Por favor, proporcione una consulta de ejemplo, por ejemplo conModel.collection.insert();..
Steve K
66
Lo mismo aquí, paso muchas horas resolviendo este problema, el documento se encuentra aquí mongoosejs.com/docs/guide.html#collection
ElvinD
3
Esto funcionó para mí. Tenía una colección de usuarios que mongorestoreé. Para acceder a él con la mangosta lo hicemongoose.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

Aquí hay una abstracción de la respuesta de Will Nathan si alguien solo quiere una función de complemento fácil de copiar y pegar:

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

simplemente haz find(collection_name, query, callback);que te den el resultado.

por ejemplo, si tengo un documento {a: 1} en una colección 'foo' y quiero enumerar sus propiedades, hago esto:

find('foo', {a : 1}, function (err, docs) {
            console.dir(docs);
        });
//output: [ { _id: 4e22118fb83406f66a159da5, a: 1 } ]
Michael Taufen
fuente
Esto es muy útil cuando se ejecutan pruebas de integración en una API
Greg
hola, ¿es esta una operación atómica? Supongamos que trato de guardar el documento en la función de devolución de llamada. ¿Será esto atómico?
Maulik Soneji
23

Puede hacer algo como esto, ya que tendrá acceso a las funciones nativas de mongodb dentro de mangosta:

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
fuente
1
¡Respuesta perfecta!
CandleCoder
15

Tuve el mismo problema y pude ejecutar una consulta sin esquema utilizando una conexión Mongoose existente con el código a continuación. He agregado una restricción simple 'a = b' para mostrar dónde agregaría dicha restricción:

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
fuente
1
Esto es exactamente lo que estaba buscando porque Mongoose no tiene soporte para gridFS. Utilizo este método para obtener metadatos de archivos de gridfs (gridstore). Simplemente reemplace questionen el código anterior con fs.filesy listo.
k00k
7

¿Estás seguro de que te has conectado a la base de datos? (Pregunto porque no veo un puerto especificado)

tratar:

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

Además, puede hacer una "muestra de colecciones" en mongo shell para ver las colecciones dentro de su base de datos, ¿tal vez intente agregar un registro a través de mangosta y ver dónde termina?

Por el aspecto de su cadena de conexión, debería ver el registro en la base de datos "test".

¡Espero eso ayude!

busticado
fuente
44
Interesante, en realidad está almacenando la información en una questionscolección cuando los datos a los que intento acceder están en una questioncolección. ¿Mongoose pluraliza automáticamente los nombres de colección / modelo?
theabraham
Sí, creo que sí ... ¡ja! Apenas estoy comenzando, así que no he explorado todos los rincones y grietas ... pero recuerdo haber visto esa brisa de castaño mientras giraba por los Grupos de Google.
busticado
3

Algo más que no era obvio, al menos para mí, fue que cuando se usa el tercer parámetro de Mongoose para evitar reemplazar la colección real con una nueva con el mismo nombre, en new Schema(...)realidad solo es un marcador de posición y no interfiere con la existencia. esquema así

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

funciona bien y devuelve todos los campos, incluso si el esquema real (remoto) no contiene ninguno de estos campos. Mongoose todavía lo querrá como new Schema(...), y una variable casi seguramente no lo pirateará.

Bart
fuente
1
me da el error 'el nombre de la colección debe ser una cadena', Editar: como respuesta de 'calvinfo', si desea dar el nombre de la colección en el constructor del modelo, simplemente pase el nombre de la colección en forma de cadena, no en el modelo de objeto. entonces su respuesta será verdadera si edita así, var User = mongoose.model ('User', new Schema ({url: String, text: String, id: Number}, 'users')); // nombre de la colección; User.find ({}, function (err, data) {console.log (err, data, data.length);});
Kaan Erkoç