Как получить доступ к существующей коллекции с Mongoose?

139

У меня есть большая коллекция из 300 questionобъектов в базе данных test. Я могу легко взаимодействовать с этой коллекцией через интерактивную оболочку MongoDB; однако, когда я пытаюсь получить коллекцию через Mongoose в приложении express.js, я получаю пустой массив.

У меня вопрос, как я могу получить доступ к этому уже существующему набору данных вместо того, чтобы воссоздать его в экспрессе? Вот некоторый код:

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

Это выводит:

null [] 0
theabraham
источник

Ответы:

252

Mongoose добавил возможность указывать имя коллекции под схемой или в качестве третьего аргумента при объявлении модели. В противном случае он будет использовать множественную версию, заданную именем, которое вы сопоставляете с моделью.

Попробуйте что-то вроде следующего, либо сопоставленное со схемой:

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

или модель сопоставлена:

mongoose.model('Question', 
               new Schema({ url: String, text: String, id: Number}), 
               'question');     // collection name
calvinfo
источник
9
Где в документах я могу найти эту информацию? Это действительно помогло, но негде объяснить множественное число.
StudioWorks
Привет @calvinfo, как я могу изменить имя коллекции во время выполнения? У меня есть 5 коллекций UserSchema, и я хочу дать каждому свое имя, например: users_server1, users_server2, users_server3 ...
Рагнар
1
Пожалуйста, приведите пример запроса, например, с Model.collection.insert();..
Стив К
6
То же самое здесь, я провожу много часов, разбираясь с этой проблемой, документ находится здесь mongoosejs.com/docs/guide.html#collection
ElvinD
3
Это сработало для меня. У меня была коллекция пользователей, которую я сохранил. Чтобы получить доступ к нему с мангустом, я сделалmongoose.connect("mongodb://localhost/fromlab"); var Schema = mongoose.Schema; var User = mongoose.model("User", new Schema({}), "users"); User.find({}, function(err, doc){ console.log((doc)) })
пустой бланк
62

Вот абстракция ответа Уилла Натана, если кому-то нужна простая надстройка для копирования и вставки:

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

просто сделать, find(collection_name, query, callback);чтобы получить результат.

например, если у меня есть документ {a: 1} в коллекции 'foo', и я хочу перечислить его свойства, я делаю это:

find('foo', {a : 1}, function (err, docs) {
            console.dir(docs);
        });
//output: [ { _id: 4e22118fb83406f66a159da5, a: 1 } ]
Майкл Тауфен
источник
Это очень полезно при выполнении интеграционных тестов на API
Грег
привет, это атомная операция? Предположим, я пытаюсь сохранить документ в функции обратного вызова. это будет атомно?
Маулик Сонеджи
23

Вы можете сделать что-то вроде этого, чем получить доступ к встроенным функциям mongodb внутри 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
Идеальный ответ!
CandleCoder
15

У меня была та же проблема, и я смог выполнить запрос без схемы, используя существующее соединение Mongoose с кодом ниже. Я добавил простое ограничение 'a = b', чтобы показать, где вы бы добавили такое ограничение:

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
Это именно то, что я искал, потому что у mongoose нет поддержки gridFS. Я использую этот метод для получения метаданных файла из gridfs (gridstore). Просто замените questionв приведенном выше коде, fs.filesи все готово.
k00k
7

Вы уверены, что подключены к БД? (Я спрашиваю, потому что я не вижу указанный порт)

пытаться:

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

Кроме того, вы можете выполнить «показ коллекций» в оболочке mongo, чтобы просмотреть коллекции в вашей базе данных - может быть, попробуйте добавить запись через mongoose и посмотреть, чем она заканчивается?

Судя по вашей строке подключения, вы должны увидеть запись в «тестовой» базе данных.

Надеюсь, поможет!

busticated
источник
4
Интересно, что на самом деле информация хранится в questionsколлекции, когда данные, к которым я пытаюсь получить доступ, находятся в questionколлекции. Mongoose автоматически плюрализует названия коллекций / моделей?
Theabraham
Да, я думаю, что это ... ха! Я только начинаю сам, поэтому я не изучил все закоулки и трюки ... но я вспоминаю, как этот легкий каштановый бриз проходил, когда я крутился в группах Google.
рухнул
3

Что-то еще, что было неочевидно, по крайней мере для меня, было то, что при использовании третьего параметра Mongoose, чтобы избежать замены фактической коллекции новой коллекцией с тем же именем, это на new Schema(...)самом деле только заполнитель, и не мешает существующим схема так

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

работает нормально и возвращает все поля - даже если фактическая (удаленная) схема не содержит ни одно из этих полей. Mongoose все еще будет хотеть это как new Schema(...), и переменная почти наверняка не взломает это.

Барт
источник
1
это дает мне ошибку 'name name должно быть строкой', Edit: как ответ 'calvinfo'. Если вы хотите дать имя коллекции в конструкторе модели, вы просто передаете имя коллекции в строковой форме, а не в объектной модели. поэтому ваш ответ будет верным, если редактировать так, var User = mongoose.model («Пользователь», новая схема ({url: String, text: String, id: Number}, 'users')); // имя коллекции; User.find ({}, function (err, data) {console.log (err, data, data.length);});
Каан Эркоч