Ż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) }.