Menu

MongoDB w Node.js: przykłady ze sterownikiem (find, insert)

Używaj MongoDB z Node.js przez oficjalny sterownik mongodb: połącz się przez MongoClient, a potem dodawaj, wyszukuj, aktualizuj i usuwaj dokumenty w kolekcji, wszystko z async/await.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Żeby używać MongoDB z Node.js, zainstaluj oficjalny sterownik (npm install mongodb), połącz się przez new MongoClient(uri), wybierz bazę przez client.db('name') i kolekcję przez db.collection('name'). Każda operacja (insertOne, find, updateOne, deleteOne) zwraca promise, więc czekasz na nią przez await. Dokumenty wchodzą i wychodzą jako zwykłe obiekty JavaScript.

Wypisuje [ 'Dune', 'Neuromancer', 'Hyperion' ]. Baza shop i kolekcja books wcześniej nie istniały: MongoDB tworzy je przy pierwszym dodaniu, a toArray() wczytuje każdy dokument, na który wskazuje kursor find().

Wyszukiwanie z filtrami i projekcją

Filtr to obiekt opisujący dokumenty, których szukasz. Zwykłe wartości pasują dokładnie; operatory takie jak $gt, $lt, $in i $regex idą do zagnieżdżonego obiektu. projection w drugim argumencie wybiera, które pola wracają.

recent zawiera dwie najnowsze książki po 1960 roku, najpierw Hyperion, potem Neuromancer, tylko z title i year; findOne zwraca pierwsze dopasowanie (albo null), a countDocuments liczy 2 książki kosztujące 10 lub więcej. Zmień $gt: 1960 na $gt: 1985, a zostanie tylko Hyperion.

Aktualizacja i usuwanie

updateOne(filter, update) zmienia pierwszy pasujący dokument. Aktualizacja używa operatorów: $set zastępuje pola, $inc dodaje do liczby, $unset usuwa pole, a $push dopisuje do tablicy. updateMany i deleteMany działają na każdym dopasowaniu.

Aktualizacja dopasowała i zmieniła jeden dokument, więc Dune kosztuje teraz 10, a w magazynie są 2 sztuki, a usunięcie książki bez zapasu zostawia 1. Aktualizacja musi używać operatorów: przekaż { price: 10 } bez $set, a sterownik ją odrzuci (cały dokument zastępuje wywołanie replaceOne).

ObjectId i indeksy

Każdy dokument dostaje _id; jeśli go nie ustawisz, sterownik tworzy ObjectId. Żeby znaleźć dokument po id, które przyszło jako string (np. z URL), opakuj je w new ObjectId(id). Indeks przyspiesza wyszukiwanie po polu, a indeks unikalny sprawia, że MongoDB odrzuca duplikaty.

ObjectId jako string ma 24 znaki szesnastkowe, a wyszukiwanie po zwykłym stringu nic nie znajduje, więc ta linia wypisuje null. Drugie dodanie łamie indeks unikalny i kończy się błędem z kodem 11000, i tak właśnie wykrywasz "e-mail jest już zajęty".

MongoDB w API Express

Połącz się raz przy starcie serwera i współdziel kolekcję; nie otwieraj nowego połączenia na każde żądanie. Sterownik trzyma pulę połączeń i używa ich ponownie.

GET /books zwraca obie książki, każdą z _id. Skopiuj jedno id do GET /books/<id>, żeby pobrać pojedynczą książkę, albo wyślij POST /books z body w JSON, np. {"title": "Foundation", "year": 1951}, i ponownie wylistuj książki.

Prawdziwa aplikacja czyta connection string z process.env.MONGODB_URI zamiast wpisywać go w kod.

Jeśli chcesz mieć schematy i walidację nad sterownikiem, opakowuje go Mongoose (npm install mongoose):

const Book = mongoose.model('Book', new mongoose.Schema({ title: String, year: Number }));
await Book.create({ title: 'Dune', year: 1965 });

Częste błędy

Zapominanie o toArray(). find() zwraca kursor, nie dokumenty. Gdy go zalogujesz, zobaczysz obiekt kursora; wywołaj toArray() albo przejdź po nim pętlą for await.

Łączenie się przy każdym żądaniu. Każdy new MongoClient otwiera własną pulę. Utwórz jednego klienta przy starcie i używaj go wszędzie.

Niezamykanie klienta w skrypcie. Otwarty klient utrzymuje proces przy życiu, gdy twój kod już skończył. Na końcu skryptów wywołuj await client.close(); serwer trzyma go otwartego przez cały czas działania.

Najczęściej zadawane pytania

Sterownik mongodb czy Mongoose?

Sterownik to oficjalna, cieńsza warstwa: pracujesz na zwykłych obiektach i własnym języku zapytań MongoDB. Mongoose dodaje na nim schematy, walidację i modele, co pomaga, gdy chcesz sprawdzać każdy dokument. Oba łączą się z tą samą bazą, a Mongoose pod spodem używa sterownika.

Czy muszę najpierw utworzyć bazę albo kolekcję?

Nie. MongoDB tworzy obie przy pierwszym dodaniu dokumentu. client.db('shop') i db.collection('books') zwracają tylko uchwyty.

Gdzie trzymać connection string?

W zmiennej środowiskowej, np. MONGODB_URI, odczytywanej przez process.env.MONGODB_URI. Connection string hostowanej bazy zawiera hasło, więc nigdy nie może trafić do repozytorium.

Dlaczego find nie zwraca dokumentów, gdy szukam po id?

_id jest zapisane jako ObjectId, a nie string, więc { _id: '65f1...' } niczego nie znajdzie. Najpierw je zamień: { _id: new ObjectId(id) }.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

Zacznij