Jak uzyskać dostęp do istniejącej kolekcji w Mongoose?

139

Mam dużą kolekcję 300 questionobiektów w bazie danych test. Mogę łatwo wchodzić w interakcje z tą kolekcją za pomocą interaktywnej powłoki MongoDB; Jednak gdy próbuję pobrać kolekcję przez Mongoose w aplikacji express.js, otrzymuję pustą tablicę.

Moje pytanie brzmi: w jaki sposób mogę uzyskać dostęp do już istniejącego zestawu danych zamiast odtwarzać go w trybie ekspresowym? Oto kod:

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

To daje:

null [] 0
theabraham
źródło

Odpowiedzi:

251

Mongoose dodał możliwość określenia nazwy kolekcji w schemacie lub jako trzeci argument podczas deklarowania modelu. W przeciwnym razie użyje wersji w liczbie mnogiej podanej pod nazwą, którą przypisujesz do modelu.

Spróbuj czegoś podobnego do poniższego, albo odwzorowanego na schemacie:

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

lub model zmapowany:

mongoose.model('Question', 
               new Schema({ url: String, text: String, id: Number}), 
               'question');     // collection name
calvinfo
źródło
9
Gdzie w dokumentacji mogę znaleźć te informacje? To naprawdę pomogło, ale nie ma miejsca na wyjaśnienie liczby mnogiej.
StudioWorks
Cześć, @calvinfo, jak mogę zmienić nazwę kolekcji w czasie wykonywania? Mam 5 kolekcji UserSchema i chcę nadać każdej z nich inną nazwę Np .: user_server1, users_server2, users_server3 ...
Ragnar
1
Proszę podać przykładowe zapytanie, np. ZModel.collection.insert();..
Steve K
6
To samo tutaj, spędzam wiele godzin na rozwiązywaniu tego problemu, dokument znajduje się tutaj mongoosejs.com/docs/guide.html#collection
ElvinD
3
To zadziałało dla mnie. Miałem kolekcję użytkowników, którą przechowałem. Aby uzyskać do niego dostęp za pomocą mangusty, zrobiłemmongoose.connect("mongodb://localhost/fromlab"); var Schema = mongoose.Schema; var User = mongoose.model("User", new Schema({}), "users"); User.find({}, function(err, doc){ console.log((doc)) })
pusty jack
61

Oto abstrakcja odpowiedzi Willa Nathana, jeśli ktoś chce tylko łatwego dodatku do kopiowania i wklejania:

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

po prostu zrób, find(collection_name, query, callback);aby otrzymać wynik.

na przykład, jeśli mam dokument {a: 1} w kolekcji „foo” i chcę wymienić jego właściwości, robię to:

find('foo', {a : 1}, function (err, docs) {
            console.dir(docs);
        });
//output: [ { _id: 4e22118fb83406f66a159da5, a: 1 } ]
Michael Taufen
źródło
Jest to bardzo pomocne podczas przeprowadzania testów integracji na interfejsie API
Greg
cześć, czy to jest operacja atomowa? Załóżmy, że spróbuję następnie zapisać dokument w funkcji wywołania zwrotnego. czy to będzie atomowe?
Maulik Soneji
23

Możesz zrobić coś takiego, niż uzyskasz dostęp do natywnych funkcji mongodb wewnątrz 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
        })
    });

});
Leo Ribeiro
źródło
1
Doskonała odpowiedź!
CandleCoder,
15

Miałem ten sam problem i mogłem uruchomić zapytanie bez schematu, używając istniejącego połączenia Mongoose z poniższym kodem. Dodałem proste ograniczenie „a = b”, aby pokazać, gdzie można dodać takie ograniczenie:

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
źródło
1
Właśnie tego szukałem, ponieważ mangusta nie ma żadnego wsparcia dla gridFS. Używam tej metody do pobierania metadanych plików z gridfs (gridstore). Po prostu zamień questionw powyższym kodzie na fs.filesi gotowe.
k00k
7

Czy na pewno połączyłeś się z bazą danych? (Pytam, ponieważ nie widzę określonego portu)

próbować:

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

Możesz także „pokazać kolekcje” w powłoce mongo, aby zobaczyć kolekcje w swojej bazie danych - może spróbuj dodać rekord za pośrednictwem mangusty i zobaczyć, gdzie się kończy?

Patrząc na parametry połączenia, powinieneś zobaczyć rekord w „testowej” bazie danych.

Mam nadzieję, że to pomoże!

zniszczony
źródło
4
Interesujące, w rzeczywistości przechowuje informacje w questionskolekcji, gdy dane, do których próbuję uzyskać dostęp, znajdują się w questionkolekcji. Czy Mongoose automatycznie tworzy liczbę mnogą nazw kolekcji / modeli?
theabraham
Tak, myślę, że tak ... ha! Dopiero zaczynam sam, więc nie zbadałem wszystkich zakamarków ... ale pamiętam, że widziałem tę małą kasztanową bryzę, gdy przeglądałem Grupy dyskusyjne Google.
zbombardowany
3

Coś innego, co nie było oczywiste, przynajmniej dla mnie, polegało na tym, że podczas używania trzeciego parametru Mongoose, aby uniknąć zastąpienia rzeczywistej kolekcji nową o tej samej nazwie, new Schema(...)jest on właściwie tylko symbolem zastępczym i nie koliduje z istniejącym schemat tak

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

działa dobrze i zwraca wszystkie pola - nawet jeśli rzeczywisty (zdalny) schemat nie zawiera żadnego z tych pól. Mongoose nadal będzie go chciał new Schema(...), a zmienna prawie na pewno go nie zhakuje.

Bart
źródło
1
daje mi błąd „nazwa kolekcji musi być ciągiem”, Edytuj: jako odpowiedź „calvinfo”. Jeśli chcesz podać nazwę kolekcji w konstruktorze modelu, po prostu podaj nazwę kolekcji w postaci ciągu, a nie modelu obiektowego. więc Twoja odpowiedź będzie prawdziwa, jeśli edytujesz w ten sposób, var User = mongoose.model ('User', new Schema ({url: String, text: String, id: Number}, 'users')); // nazwa kolekcji; User.find ({}, function (err, data) {console.log (err, data, data.length);});
Kaan Erkoç