Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik11 min czytania

MongoDB Atlas Vector Search, wyszukiwanie wektorowe

MongoDB Atlas Vector Search dodaje wektory do bazy dokumentowej. Etap $vectorSearch, kwantyzacja, modele Voyage i porównanie z dedykowanymi bazami.

MongoDB Atlas Vector Search, wyszukiwanie wektorowe

MongoDB Atlas Vector Search dokłada wyszukiwanie po podobieństwie wektorowym do bazy dokumentowej, w której trzymasz już dane aplikacji. Wektor jest zwykłym polem dokumentu, a zapytanie etapem potoku agregacji, więc nie ma osobnego systemu do zsynchronizowania. Od 2025 roku platforma ma też własne modele osadzeń, przejęte razem z firmą Voyage AI.

Główna zaleta: brak drugiego systemu

Typowa architektura wyszukiwania semantycznego wygląda tak, że dane produkcyjne leżą w jednej bazie, a wektory w drugiej. Brzmi niewinnie, dopóki nie policzysz, co z tego wynika. Trzeba utrzymać ścieżkę synchronizacji, obsłużyć sytuację, w której zapis do jednej bazy się udał, a do drugiej nie, i pogodzić się z tym, że wyniki wyszukiwania wskazują na dokumenty, których treść trzeba dociągnąć osobnym zapytaniem.

Tutaj tego problemu nie ma, bo wektor jest polem tego samego dokumentu, co reszta danych. Zapis jest jeden i albo się udaje w całości, albo nie. Wynik wyszukiwania zawiera od razu wszystkie pola, więc nie ma drugiego przejścia po treść.

Drugą konsekwencją jest filtrowanie. Skoro w tym samym dokumencie leżą metadane, warunek typu „tylko dokumenty tego użytkownika z ostatnich trzydziestu dni" jest zwykłym filtrem, a nie mechanizmem doklejanym z boku. W dedykowanych bazach wektorowych metadane trzeba duplikować, a każda ich zmiana wymaga aktualizacji w dwóch miejscach.

Uczciwie trzeba za to opisać sprawę własnej infrastruktury, bo tu wiele materiałów jest już nieaktualnych. Wyszukiwanie obsługuje osobny proces, mongot, działający obok właściwej bazy i utrzymywany z nią w zgodzie przez strumienie zmian. Od września 2025 roku ten proces da się uruchomić także poza usługą zarządzaną: wyszukiwanie pełnotekstowe i wektorowe jest dostępne w darmowej edycji Community od wersji 8.2 oraz w wydaniu Enterprise, więc zdanie o tym, że wektorów bez chmury się nie da, przestało być prawdziwe. Zastrzeżenia są jednak poważne. To wciąż publiczny podgląd, przez producenta przeznaczony do prac rozwojowych i oceny, a nie do produkcji, i uruchamia się wyłącznie na Linuksie. Jeśli warunkiem projektu jest produkcyjne wyszukiwanie wektorowe na własnych serwerach już dziś, rozsądniej sięgnąć po Qdrant albo Milvus.

Indeks i zapytanie

Indeks definiuje się jako dokument JSON, w którym każde pole ma typ vector albo filter. Pierwszy opisuje samo osadzenie, drugi pola, po których będziesz zawężał wyniki.

Code
JSON
{
  "fields": [
    {
      "type": "vector",
      "path": "osadzenie",
      "numDimensions": 1536,
      "similarity": "cosine"
    },
    { "type": "filter", "path": "wlasciciel" },
    { "type": "filter", "path": "data_utworzenia" }
  ]
}

Liczba wymiarów musi zgadzać się co do jednego z wyjściem Twojego modelu. Miara podobieństwa ma trzy warianty: cosine, dotProduct i euclidean. Do wyszukiwania semantycznego domyślnie bierze się miarę kosinusową, bo patrzy na kierunek wektora, a nie na jego długość. Iloczyn skalarny daje to samo uszeregowanie, o ile wektory są znormalizowane, i jest wtedy tańszy obliczeniowo.

Zapytanie to etap potoku agregacji:

Code
JavaScript
db.dokumenty.aggregate([
  {
    $vectorSearch: {
      index: "indeks_osadzen",
      path: "osadzenie",
      queryVector: wektorPytania,
      numCandidates: 200,
      limit: 10,
      filter: { wlasciciel: uzytkownikId }
    }
  },
  { $project: { tytul: 1, tresc: 1, wynik: { $meta: "vectorSearchScore" } } }
])

Trzy ograniczenia tego etapu warto zapamiętać, bo każde z nich potrafi zablokować projekt w połowie. Musi być pierwszym etapem potoku, w którym występuje. Nie da się go użyć w definicji widoku, w podpotoku łączenia dokumentów ani w etapie rozgałęziającym potok. Wyniki można przekazać dalej, w tym do łączenia, ale samo wyszukiwanie zawsze zaczyna potok.

numCandidates, czyli najważniejszy parametr

To ten parametr decyduje o kompromisie między trafnością a czasem odpowiedzi, a jest jednocześnie najczęściej ustawiany na chybił trafił.

Mechanizm działa tak: wyszukiwanie przybliżone przechodzi po grafie sąsiedztwa i utrzymuje kolejkę kandydatów o rozmiarze podanym w numCandidates. Im większa kolejka, tym większa szansa, że prawdziwie najbliższy dokument znajdzie się w wynikach, i tym dłużej trwa zapytanie.

Dokumentacja podaje konkretną regułę: ustaw numCandidates co najmniej dwadzieścia razy wyżej niż limit. Przy dziesięciu wynikach oznacza to dwieście kandydatów, co daje pokrycie z wyszukiwaniem dokładnym na poziomie mniej więcej dziewięćdziesięciu do dziewięćdziesięciu pięciu procent. To rozsądny punkt startowy, którego nie warto zmieniać bez pomiaru.

Jeśli potrzebujesz stuprocentowej dokładności, jest wariant exact ustawiony na prawdę, który przegląda wszystkie wektory zamiast korzystać z grafu. Przy małych zbiorach albo przy bardzo wąskim filtrze bywa szybszy niż wyszukiwanie przybliżone, bo po odsianiu zostaje niewiele dokumentów. To niedoceniana opcja: jeśli filtr zostawia kilkaset dokumentów, przegląd zupełny jest zwykle lepszym wyborem niż strojenie kolejki kandydatów.

Kwantyzacja, czyli jak zmieścić się w pamięci

Pamięć jest tu głównym kosztem, bo indeks wektorowy musi w niej rezydować. Kwantyzacja polega na zapisaniu współrzędnych z mniejszą precyzją i występuje w dwóch wariantach.

WariantZapis współrzędnejZmniejszenie wektoraZmniejszenie pamięci procesu wyszukiwania
Bez kwantyzacji32 bitybrakbrak
Skalarna8 bitów4 razy3,75 razy
Binarna1 bit32 razy24 razy

Kwantyzacja skalarna to bezpieczny wybór domyślny. Czterokrotna oszczędność przy niewielkiej stracie trafności to zwykle najlepszy stosunek zysku do ryzyka, jaki da się tu uzyskać jednym ustawieniem.

Binarna jest bardziej radykalna i wymaga zrozumienia jednej rzeczy. Przy zapisie jednobitowym porównanie dwóch wektorów sprowadza się do liczenia różniących się bitów, co jest operacją bardzo szybką, ale ubogą informacyjnie. Dlatego binarna kwantyzacja zyskuje na dokładności wraz ze wzrostem liczby kandydatów, podczas gdy skalarna osiąga swój pułap wcześniej. Wnioski z pomiarów producenta są takie, że przy dużej liczbie kandydatów binarna dogania skalarną, a bywa że ją wyprzedza, kosztem wyraźnie dłuższego czasu odpowiedzi powyżej tysiąca kandydatów.

Praktyczna reguła: zacznij od skalarnej. Po binarną sięgaj wtedy, gdy zbiór jest na tyle duży, że pamięć staje się realnym ograniczeniem budżetu, i gdy jesteś gotów zapłacić za to wyższą liczbą kandydatów.

Modele osadzeń w środku platformy

W lutym 2025 roku MongoDB przejął firmę Voyage AI za około 220 milionów dolarów, a powodem były modele osadzeń i przeszeregowania. Konsekwencje tej decyzji widać dziś w produkcie.

Najważniejszą jest automatyczne generowanie osadzeń, dostępne w publicznym podglądzie w edycji Community od stycznia 2026 roku, a w Atlasie od 11 maja 2026 roku. Zamiast liczyć wektor po swojej stronie i zapisywać go razem z dokumentem, wskazujesz pole tekstowe i model, a baza sama liczy osadzenia przy zapisie i sama je aktualizuje przy zmianie treści.

To usuwa całą klasę błędów, o których zwykle nikt nie myśli przy projektowaniu. Dokument zmodyfikowany bez przeliczenia wektora zostaje w indeksie ze starą reprezentacją i cicho psuje wyniki. Wsad historyczny przetworzony innym modelem niż nowe dokumenty daje zbiór, w którym stare i nowe rekordy nie konkurują ze sobą sensownie. Automatyczne osadzanie zdejmuje odpowiedzialność za te dwa przypadki.

Cena jest taka, że wiążesz się z modelami jednego dostawcy. Rodzina Voyage 4 obejmuje kilka wariantów o różnym rozmiarze, a jakość tych modeli jest wysoka, natomiast zmiana na model spoza platformy oznacza powrót do ręcznego liczenia wektorów. Więcej o samych modelach znajdziesz przy okazji Voyage AI.

Porównanie z dedykowanymi bazami

CechaAtlas Vector SearchMilvusPineconepgvector
Dane i wektory razemtaknienietak
Self hostingpodgląd publiczny, Community 8.2+taknietak
Filtrowanie po metadanychnaturalne, w dokumencieosobne polaosobne polanaturalne, w wierszu
Automatyczne osadzeniatak, modele Voyagenieczęściowonie
Docelowa skaladziesiątki milionówmiliardymiliardymiliony
Koszt przy małym zbiorzeniski, jeśli już masz Atlaswysokiśredninajniższy

Reguła wyboru jest tu prostsza niż w innych porównaniach. Jeśli dane aplikacji już leżą w MongoDB, dokładanie osobnej bazy wektorowej jest decyzją, którą trzeba uzasadnić, a nie domyślną ścieżką. Jeśli leżą w PostgreSQL, ta sama logika prowadzi do rozszerzenia pgvector. Dedykowane bazy zaczynają wygrywać przy skali, przy której koszt pamięci przewyższa koszt utrzymania dodatkowego systemu, a to zwykle setki milionów wektorów.

Koszt i kiedy to przestaje się opłacać

Rachunek za tę usługę nie jest osobną pozycją obok bazy, tylko konsekwencją rozmiaru klastra, i to jest zarówno zaletą, jak i pułapką. Zaletą, bo przy małym zbiorze wyszukiwanie wektorowe praktycznie nic nie kosztuje ponad to, co już płacisz. Pułapką, bo indeks wektorowy musi mieścić się w pamięci, więc w pewnym momencie wymusza przejście na większy poziom klastra, a ten podnosi rachunek za wszystko naraz, także za tę część danych, która z wektorami nie ma nic wspólnego.

Warto zrobić prosty rachunek przed decyzją. Weź liczbę dokumentów, pomnóż przez liczbę wymiarów modelu i przez cztery bajty, a potem podziel przez współczynnik kwantyzacji, którą zamierzasz włączyć. Milion dokumentów przy tysiącu pięciuset wymiarach to około sześciu gigabajtów bez kwantyzacji i około półtora gigabajta przy skalarnej. Ta jedna liczba mówi, na jakim poziomie klastra wylądujesz, i jest wiarygodniejsza niż jakikolwiek kalkulator, bo opiera się na Twoim modelu.

Moment, w którym warto rozważyć wyprowadzenie wektorów na zewnątrz, poznasz po tym, że powiększasz klaster wyłącznie z powodu indeksu, a nie z powodu ruchu czy rozmiaru danych. Wtedy dedykowana baza wektorowa, płacona osobno i skalowana niezależnie, zaczyna być tańsza mimo kosztu utrzymania drugiego systemu. Dopóki jednak klaster rośnie z powodów mieszanych, dzielenie danych na dwa miejsca zwykle pogarsza sytuację zamiast ją poprawiać.

Typowe błędy

Pierwszy to pominięcie pól filtrujących w definicji indeksu. Warunek podany w zapytaniu na polu, którego nie zadeklarowano jako filter, nie zadziała tak, jak się spodziewasz, a komunikat nie zawsze wskazuje przyczynę wprost. Pola do filtrowania deklaruj razem z wektorem, od pierwszej wersji indeksu.

Drugi to zbyt niska liczba kandydatów przy jednoczesnym filtrowaniu. Filtr zawęża zbiór, więc kolejka kandydatów wyczerpuje się szybciej i wyniki potrafią być gorsze, niż wynikałoby z samej reguły dwudziestokrotności. Przy wąskich filtrach albo podnieś liczbę kandydatów, albo przejdź na wyszukiwanie dokładne.

Trzeci to trzymanie w jednym polu wektorów z dwóch różnych modeli. Zdarza się to przy zmianie dostawcy osadzeń w trakcie życia projektu i daje wyniki, które wyglądają na losowe. Zmiana modelu wymaga przeliczenia całego zbioru, nie tylko nowych dokumentów.

Czwarty to zapominanie o rozmiarze dokumentu. Wektor o tysiącu wymiarów zapisany jako tablica liczb zmiennoprzecinkowych zajmuje w dokumencie sporo miejsca, a limit rozmiaru dokumentu w MongoDB jest twardy. Przy kilku wektorach w jednym dokumencie warto to policzyć, zanim wsad się zatrzyma.

Piąty to używanie wyszukiwania wektorowego tam, gdzie wystarczy dopasowanie tekstowe. Zapytanie o numer faktury albo o dokładną nazwę produktu obsłuży zwykły indeks, szybciej i taniej. Wektory są odpowiedzią na pytania sformułowane opisowo, nie na wyszukiwanie identyfikatorów.

Wpięcie w stos aplikacji

W typowym systemie wyszukiwania wspomaganego generowaniem ta baza pełni obie role naraz: przechowuje dokumenty i obsługuje wyszukiwanie. Integracje po stronie LangChaina i LlamaIndeksu są gotowe, więc podłączenie sprowadza się do wskazania kolekcji i nazwy indeksu.

Jedna decyzja projektowa zasługuje na uwagę, bo wraca w każdym takim wdrożeniu. Chodzi o to, czy dzielić dokumenty na fragmenty i zapisywać każdy jako osobny dokument, czy trzymać tablicę fragmentów w jednym. Osobne dokumenty są prostsze w obsłudze i naturalnie współgrają z etapem wyszukiwania, kosztem powielenia metadanych. Tablica w jednym dokumencie oszczędza miejsce, ale komplikuje zapytania i szybciej zbliża się do limitu rozmiaru. Przy większości zastosowań pierwsze podejście starzeje się lepiej, a powielone metadane są tańsze niż komplikacja potoku.

FAQ

Czy Atlas Vector Search działa na własnym serwerze?

Tak, choć z zastrzeżeniami. Wyszukiwanie obsługuje osobny proces działający obok bazy i od września 2025 roku można go uruchomić również w edycji Community od wersji 8.2 oraz w wydaniu Enterprise. To nadal publiczny podgląd, przeznaczony przez producenta do prac rozwojowych i oceny, a nie do produkcji, i tylko na Linuksie. Przy produkcyjnym wymogu trzymania danych na własnej infrastrukturze dedykowana baza wektorowa pasuje dziś lepiej.

Jak dobrać wartość numCandidates?

Zacznij od dwudziestokrotności limitu wyników, bo taka relacja daje pokrycie z wyszukiwaniem dokładnym rzędu dziewięćdziesięciu procent. Podnoś ją, jeśli filtrujesz wąsko albo jeśli pomiar trafności na Twoich zapytaniach wypada słabo.

Skalarna czy binarna kwantyzacja?

Skalarna jako domyślna, bo daje czterokrotną oszczędność pamięci przy niewielkiej stracie trafności. Binarna dopiero wtedy, gdy pamięć jest realnym ograniczeniem, i z gotowością na wyższą liczbę kandydatów, bo bez tego trafność wyraźnie spada.

Czy muszę sam liczyć osadzenia?

Nie musisz. Automatyczne osadzanie z modelami Voyage jest dostępne w publicznym podglądzie, w Atlasie od maja 2026 roku, i samo generuje oraz aktualizuje wektory przy zapisie dokumentu. Ręczne liczenie zostaje opcją dla tych, którzy chcą użyć modelu spoza platformy.

Czy da się połączyć wyszukiwanie wektorowe z tekstowym?

Tak, przez połączenie wyników dwóch zapytań w jednym potoku agregacji i wspólne uszeregowanie. To rozwiązanie wymaga więcej pracy niż gotowy mechanizm łączenia rang znany z wyszukiwarek pełnotekstowych, ale daje pełną kontrolę nad sposobem ważenia obu list.

Szczegóły składni opisuje dokumentacja etapu $vectorSearch, a warianty kwantyzacji strona o kwantyzacji wektorów.