Como acessar uma coleção preexistente com o Mongoose?


139

Eu tenho uma grande coleção de 300 questionobjetos em um banco de dados test. Eu posso interagir com esta coleção facilmente através do shell interativo do MongoDB; no entanto, quando tento obter a coleção pelo Mongoose em um aplicativo express.js, obtenho uma matriz vazia.

Minha pergunta é: como posso acessar esse conjunto de dados já existente em vez de recriá-lo no express? Aqui está um 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); });

Isso gera:

null [] 0

Respostas:


251

O Mongoose adicionou a capacidade de especificar o nome da coleção no esquema ou como o terceiro argumento ao declarar o modelo. Caso contrário, ele usará a versão pluralizada fornecida pelo nome que você mapeia para o modelo.

Tente algo como o seguinte, mapeado por esquema:

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

ou modelo mapeado:

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

9
Onde nos documentos posso encontrar essas informações? Isso realmente ajudou, mas não há lugar para explicar a coisa plural.
StudioWorks

Olá, @calvinfo, como posso alterar o nome da coleção em tempo de execução? Eu tenho 5 coleções de UserSchema e eu quero dar a cada um um nome diferente Por exemplo: users_server1, users_server2, users_server3 ...
Ragnar

1
Por favor, forneça um exemplo de consulta, por exemplo, com #Model.collection.insert();..
Steve K

6
Mesmo aqui, eu passar muitas horas tentando descobrir este problema, o documento é encontrado aqui mongoosejs.com/docs/guide.html#collection
ElvinD

3
Isso funcionou para mim. Eu tinha uma coleção de usuários que eu armazenava mais. Para obter acesso a ele com mangusto eu fizmongoose.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 em branco

61

Aqui está uma abstração da resposta de Will Nathan se alguém quiser apenas uma função fácil de copiar e colar:

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

simplesmente faça find(collection_name, query, callback);para receber o resultado.

por exemplo, se eu tiver um documento {a: 1} em uma coleção 'foo' e desejar listar suas propriedades, faça o seguinte:

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

Isso é muito útil ao executar testes de integração em uma API
Greg

oi, isso é uma operação atômica? Suponha que eu tente salvar o documento na função de retorno de chamada. isso será atômico?
Maulik Soneji

23

Você pode fazer algo assim, para acessar as funções nativas do mongodb no 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
Resposta perfeita!
21818 CandleCoder

15

Eu tive o mesmo problema e consegui executar uma consulta sem esquema usando uma conexão Mongoose existente com o código abaixo. Adicionei uma restrição simples 'a = b' para mostrar onde você adicionaria essa restrição:

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
Era exatamente isso que eu procurava, porque o mangusto não tem nenhum suporte ao gridFS. Eu uso esse método para obter metadados de arquivo do gridfs (gridstore). Basta substituir questiono código acima por fs.filese pronto.
K00k

7

Tem certeza de que você se conectou ao banco de dados? (Pergunto porque não vejo uma porta especificada)

experimentar:

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

Além disso, você pode fazer um "show collections" no mongo shell para ver as coleções no seu db - talvez tente adicionar um registro via mongoose e ver onde ele termina?

Na aparência da sua seqüência de conexão, você deve ver o registro no banco de dados "test".

Espero que ajude!


4
Interessante, é realmente armazenar as informações em uma questionscoleção quando os dados que estou tentando acessar estão em uma questioncoleção. O Mongoose pluraliza automaticamente os nomes de coleções / modelos?
Theabraham 27/04

Sim, eu acho que sim ... ha! Estou apenas começando, então não explorei todos os cantos e recantos ... mas lembro-me de ter visto aquela brisa leve quando eu estava girando nos Grupos do Google.
busticated

3

Outra coisa que não era óbvia, para mim, pelo menos, foi que, ao usar o terceiro parâmetro do Mongoose para evitar a substituição da coleção real por uma nova com o mesmo nome, na new Schema(...)verdade é apenas um espaço reservado e não interfere na existência. esquema assim

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 bem e retorna todos os campos - mesmo que o esquema (remoto) real não contenha nenhum desses campos. O Mongoose ainda o desejará new Schema(...), e uma variável quase certamente não o invadirá.


1
ele fornece o erro 'nome da coleção deve ser string' para mim, Edit: como resposta de 'calvinfo', se você deseja fornecer o nome da coleção no construtor do modelo, basta passar o nome da coleção na forma de string e não no modelo de objeto. portanto, sua resposta será verdadeira se editar assim: var User = mongoose.model ('Usuário', novo esquema ({url: String, texto: String, id: Number}, 'users')); // nome da coleção; User.find ({}, função (err, dados) {console.log (err, dados, comprimento dos dados);});
Kaan Erkoç
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.