Bagaimana cara mengakses koleksi yang sudah ada sebelumnya dengan Mongoose?


143

Saya memiliki banyak koleksi 300 questionobjek dalam database test. Saya dapat berinteraksi dengan koleksi ini dengan mudah melalui shell interaktif MongoDB; namun, ketika saya mencoba untuk mendapatkan koleksi melalui Mongoose dalam aplikasi express.js saya mendapatkan array kosong.

Pertanyaan saya adalah, bagaimana saya bisa mengakses dataset yang sudah ada ini alih-alih membuatnya kembali secara ekspres? Berikut beberapa kode:

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

Output ini:

null [] 0

Jawaban:


260

Mongoose menambahkan kemampuan untuk menentukan nama koleksi di bawah skema, atau sebagai argumen ketiga saat mendeklarasikan model. Jika tidak, model akan menggunakan versi jamak yang diberikan oleh nama yang Anda petakan ke model.

Cobalah sesuatu seperti berikut, baik yang dipetakan skema:

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

atau model yang dipetakan:

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

9
Di manakah dalam dokumen saya dapat menemukan informasi ini? Ini sangat membantu tetapi tidak ada tempat yang menjelaskan hal jamak.
StudioWorks

Hai, @calvinfo bagaimana cara mengubah nama koleksi saat runtime? Saya memiliki 5 koleksi UserSchema dan saya ingin memberikan masing-masing nama yang berbeda Misalnya: users_server1, users_server2, users_server3 ...
Ragnar

1
Pleae memberikan contoh permintaan, misalnya denganModel.collection.insert();..
Steve K

6
Sama di sini, saya menghabiskan waktu berjam-jam untuk mencari tahu masalah ini, dokumennya ditemukan di sini mongoosejs.com/docs/guide.html#collection
ElvinD

3
Ini berhasil untuk saya. Saya memiliki koleksi pengguna yang saya simpan. Untuk mendapatkan akses ke sana dengan luwak yang saya lakukanmongoose.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

Berikut adalah abstraksi dari jawaban Will Nathan jika ada yang hanya menginginkan fungsi add-in salin-tempel yang mudah:

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

lakukan saja find(collection_name, query, callback);untuk mendapatkan hasil.

misalnya, jika saya memiliki dokumen {a: 1} dalam koleksi 'foo' dan saya ingin mencantumkan propertinya, saya melakukan ini:

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

Ini sangat membantu saat menjalankan pengujian integrasi pada API
Greg

hai, apakah ini operasi atom? Misalkan saya mencoba untuk kemudian menyimpan dokumen dalam fungsi panggilan balik. apakah ini akan menjadi atom?
Maulik Soneji

27

Anda dapat melakukan sesuatu seperti ini, daripada Anda akan mengakses fungsi mongodb asli di dalam luwak:

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
Jawaban yang tepat!
CandleCoder

15

Saya memiliki masalah yang sama dan dapat menjalankan kueri tanpa skema menggunakan koneksi Mongoose yang ada dengan kode di bawah ini. Saya telah menambahkan batasan sederhana 'a = b' untuk menunjukkan di mana Anda akan menambahkan batasan seperti itu:

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
Inilah yang saya cari karena luwak tidak memiliki dukungan gridFS. Saya menggunakan metode ini untuk mengambil metadata file dari gridfs (gridstore). Cukup ganti questionkode di atas dengan fs.filesdan Anda siap melakukannya.
k00k

7

Apakah Anda yakin telah terhubung ke db? (Saya bertanya karena saya tidak melihat port yang ditentukan)

mencoba:

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

Juga, Anda dapat melakukan "show collections" di mongo shell untuk melihat koleksi dalam db Anda - mungkin coba tambahkan catatan melalui luwak dan lihat di mana akhirnya?

Dari tampilan string koneksi Anda, Anda akan melihat record di "test" db.

Semoga membantu!


4
Menarik, sebenarnya menyimpan informasi dalam questionskoleksi ketika data yang saya coba akses ada dalam questionkoleksi. Apakah Mongoose secara otomatis membuat jamak nama koleksi / model?
theabraham

Ya saya pikir itu benar ... ha! Saya baru saja memulai sendiri jadi saya belum menjelajahi semua celah dan celah ... tapi saya ingat pernah melihat angin kastanye saat saya berputar-putar di Google Grup.
rusak

4

Hal lain yang tidak jelas, setidaknya bagi saya, adalah bahwa ketika menggunakan parameter ketiga Mongoose untuk menghindari penggantian koleksi sebenarnya dengan yang baru dengan nama yang sama, new Schema(...)sebenarnya hanya placeholder, dan tidak mengganggu eksisitng skema jadi

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

berfungsi dengan baik dan mengembalikan semua bidang - meskipun Skema (jarak jauh) aktual tidak berisi bidang ini. Mongoose akan tetap menginginkannya sebagai new Schema(...), dan variabel hampir pasti tidak akan meretasnya.


1
itu memberikan kesalahan 'nama koleksi harus string' kepada saya, Edit: sebagai jawaban 'calvinfo', Jika Anda ingin memberikan nama koleksi dalam model konstruktor Anda cukup meneruskan nama koleksi dalam bentuk string bukan model objek. jadi jawaban anda akan benar jika edit seperti ini, var User = mongoose.model ('User', new Schema ({url: String, text: String, id: Number}, 'users')); // nama koleksi; User.find ({}, function (err, data) {console.log (err, data, data.length);});
Kaan Erkoç
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.