Ga naar hoofdinhoud

Vector Search in MongoDB onder de knie: een gids met voorbeelden

Leer hoe je MongoDB's Vector Search instelt en gebruikt voor slimme apps. Deze praktische gids behandelt vectorindexering, best practices voor queries en voorbeelden uit de praktijk.
· 7 min lezen

Verken met AI

Vectorindexering is uitgegroeid tot een krachtig hulpmiddel voor het bouwen van moderne applicaties. Het maakt snelle en efficiënte similarity searches mogelijk op hoog-dimensionale data, vaak vector embeddings genoemd. Deze mogelijkheid is nu naadloos geïntegreerd in MongoDB, zodat ontwikkelaars geavanceerde features direct in hun database kunnen bouwen.

Dit artikel is een praktische gids voor het instellen en gebruiken van vectorindexering in MongoDB. We lopen stap voor stap het proces door, van het maken van je eerste index tot het draaien van complexe queries. Je leert ook best practices en bekijkt een realistisch voorbeeld van het bouwen van een productaanbevelingssysteem voor een e-commercestore.

Wat is vectorindexering?

In de kern is vectorindexering een techniek om vector-embeddings te organiseren om similarity searches te versnellen. In tegenstelling tot traditionele indexen die werken op scalaire waarden (zoals getallen of strings), is een vectorindex geoptimaliseerd om "naburige" vectors te vinden in een multidimensionale ruimte.

Vector-embeddings zijn numerieke representaties van complexe data, waaronder tekst, afbeeldingen en audio. Zo kan een productbeschrijving worden omgezet in een vector waarbij vergelijkbare producten vectors hebben die dichter bij elkaar liggen in de ruimte. Deze nabijheid maakt krachtige toepassingen mogelijk, zoals:

  • Semantisch zoeken: Producten vinden op basis van de betekenis van een query, niet alleen op trefwoorden.
  • Aanbevelingssystemen: Producten of content suggereren op basis van gebruikersvoorkeuren.
  • Beeldherkenning: Vergelijkbare afbeeldingen identificeren in een grote database.

Vectorindexering instellen in MongoDB

Om te beginnen heb je een MongoDB Atlas-cluster nodig. Vector search is een cloud-native feature. Je kunt deze feature uitproberen op MongoDB Atlas of in de gratis Community edition. In dit artikel gebruiken we MongoDB Atlas.

Stap 1: Maak een MongoDB Atlas-cluster 

Maak een nieuw cluster in MongoDB Atlas. De gratis M0-laag is voldoende om te testen.

Stap 2: Maak een collectie en voeg data toe 

Maak eerst verbinding met je cluster via MongoDB Shell (mongosh) of je favoriete driver. Maak daarna een nieuwe collectie met de naam products en voeg documenten in met een veld voor een vector. Elk document vertegenwoordigt een product en bevat een embedding-veld, waarin de vectorrepresentatie van het product staat.

Hier is een vollediger voorbeeld met drie verschillende productdocumenten, elk met een willekeurig gegenereerde vector om te laten zien hoe de data eruit kan zien. In een praktijksituatie vervang je deze door embeddings die zijn gegenereerd door een AI-model.

db.products.insertMany([
  {
    "name": "Wireless Noise-Canceling Headphones",
    "category": "Electronics",
    "description": "Premium over-ear headphones with active noise cancellation and a 30-hour battery life.",
    "price": 249.99,
    "embedding": [0.012, 0.054, 0.089, -0.031, 0.067, 0.021, -0.045, 0.098, 0.011, -0.076, 0.033, -0.015, -0.087, 0.059, 0.009, 0.042]
  },
  {
    "name": "Smart Coffee Maker",
    "category": "Home Goods",
    "description": "Programmable coffee machine that can be controlled from your smartphone. Brews up to 12 cups.",
    "price": 129.99,
    "embedding": [0.056, 0.023, 0.011, 0.078, -0.029, 0.041, 0.087, -0.019, 0.065, 0.002, -0.093, 0.018, 0.057, -0.041, 0.022, 0.064]
  },
  {
    "name": "Ultra-light Backpack",
    "category": "Travel",
    "description": "Durable and lightweight backpack with multiple compartments, perfect for hiking or daily commutes.",
    "price": 79.99,
    "embedding": [-0.072, 0.034, 0.019, 0.068, -0.055, 0.081, 0.004, -0.025, 0.039, 0.016, -0.044, 0.062, 0.008, 0.071, -0.013, 0.053]
  }
]);

Elk document bevat een name, category, description en price, plus het cruciale embedding-veld. De embedding is een array met vaste lengte die de semantische betekenis van de productbeschrijving weergeeft. De grootte van deze array, ofwel de dimensionaliteit, hangt af van het model dat de embeddings maakt. In dit voorbeeld is de dimensionaliteit 128.

Dit is de data waarop we onze vectorindex bouwen om semantisch zoeken en productaanbevelingen mogelijk te maken.

Stap 3: Maak een vectorindex

Zodra je data met embeddings in een collectie staat, is de volgende stap het maken van een vectorindex. Deze index is cruciaal voor snelle en efficiënte similarity searches. Het onderstaande commando gebruikt createSearchIndex om een vectorindex te bouwen op het veld embedding.

db.products.createSearchIndex({
  "name": "vector_index",
  "definition": {
    "mappings": {
      "dynamic": true,
      "fields": [
        {
          "type": "vector",
          "path": "embedding",
          "numDimensions": 128, 
          "similarity": "cosine"
        }
      ]
    },
  }
});

De configuratie begrijpen

De indexconfiguratie wordt gedefinieerd in de definition-objectenarray fields. Deze structuur is het blauwdruk voor hoe MongoDB Atlas je vectors organiseert voor snelle terughaalacties.

De kernparameters voor vectorindexering zijn:

  • path: Dit specificeert de exacte naam van het veld in je documenten dat de vectorarray bevat; in dit voorbeeld is dat "embedding".
  • numDimensions: Dit is de belangrijkste parameter. Deze moet exact overeenkomen met het aantal elementen in de vectorarray die je embeddingmodel produceert (bijv. 128, 768, 1536).
  • similarity: Dit definieert de wiskundige maatstaf die tijdens een zoekopdracht de "nabijheid" tussen twee vectors berekent.
    • cosine wordt doorgaans aanbevolen voor semantisch zoeken, omdat het de hoek tussen vectors meet en zich richt op semantische richting.
    • Andere opties zijn euclidean (rechte-lijn-afstand) en dotProduct.

Optionele performance-parameters

Voor geavanceerde performance-tuning laat MongoDB Atlas je optionele parameters opgeven om opslag en geheugen te optimaliseren:

  • quantization: Deze parameter wordt gebruikt om je vectors te comprimeren, wat de indexgrootte en het geheugengebruik aanzienlijk vermindert.
    • scalar of binary kan worden opgegeven om vectors te kwantiseren, waarbij je een klein beetje recall inruilt voor grote winst in opslag en snelheid.

Vector Search-queries uitvoeren

Zodra de index is gebouwd, kun je de $vectorSearch-aggregatiestap gebruiken om similarity queries uit te voeren.

Laten we de producten vinden die het meest lijken op een queryvector. Deze query wordt meestal gegenereerd op basis van de zoekopdracht van een gebruiker.

// A sample query vector, generated from a user's search for "wireless audio device"
const queryVector = [0.11, 0.22, 0.33, ...];

db.products.aggregate([
  {
    "$vectorSearch": {
      "queryVector": queryVector,
      "path": "embedding",
      "numCandidates": 100, // Number of documents to scan
      "limit": 5 // Number of results to return
    }
  },
  {
    "$project": {
      "name": 1,
      "description": 1,
      "_id": 0
    }
  }
]);
  • queryVector: De vector waar je naar zoekt.
  • path: De naam van het veld met de vector-embeddings.
  • numCandidates: Het aantal kandidaatdocumenten dat in de index wordt gescand. Een hoger aantal verbetert de nauwkeurigheid maar verhoogt de latentie.
  • limit: Het aantal toppresultaten dat wordt geretourneerd.

De stap $project is optioneel, maar handig om de output vorm te geven en de vectordata uit het resultaat te houden.

Best practices voor vectorindexering

Bij het tunen van je vectorindex voor optimale performance, moet je nauwkeurigheid en snelheid in balans brengen. Het komt neer op het aanpassen van de indexparameters op basis van je dataset en performance-doelen.

De juiste similariteitsmetric kiezen

De keuze van de metric is fundamenteel, omdat deze bepaalt hoe "vergelijkbaar" twee vectors zijn. Raadpleeg de MongoDB-docs voor meer informatie over de velden.

  • cosine: Het beste voor semantische gelijkenis, met name bij tekst. Het meet de hoek tussen vectors en negeert hun lengte. Dit is belangrijk bij modellen waar vectorlengte niet betekenisvol is.
  • euclidean: Meet de rechte-lijn-afstand tussen twee vectors. Gebruik dit als de grootte (of lengte) van de vectors betekenisvol is, bijvoorbeeld bij datatypes waar een hogere waarde een sterker kenmerk aangeeft.
  • dotProduct: Berekent het inproduct van twee vectors. Deze metric wordt vaak gebruikt voor aanbevelingssystemen. Wanneer vector-embeddings genormaliseerd zijn tot lengte 1, is het inproduct functioneel gelijk aan cosine similarity.

Embedding-dimensies beheren

De parameter dimensions is cruciaal en moet exact overeenkomen met de output van je embeddingmodel. Een veelgemaakte fout is een getal kiezen dat niet overeenkomt met de modeloutput. Een model met meer dimensies kan meer detail vastleggen, maar resulteert in een grotere index en mogelijk langzamere queries. Controleer altijd de documentatie van je model om de dimensionaliteit te bevestigen (bijv. OpenAI's text-embedding-ada-002 heeft 1536 dimensies).

Index-tuning

De parameters numCandidates en numLists zijn cruciaal om snelheid en nauwkeurigheid in balans te brengen. Een goede vuistregel is om te beginnen met een lage numCandidates en die te verhogen totdat je een acceptabel nauwkeurigheidsniveau bereikt. Je kunt ook experimenteren met verschillende waarden voor numLists bij ivf-indexen om de sweet spot voor jouw dataset te vinden.

Voorbeeld: een simpel aanbevelingssysteem bouwen

Laten we deze concepten toepassen op een praktisch voorbeeld: een productaanbevelingssysteem voor e-commerce.

Stap 1: Sla productdata met embeddings op

We slaan eerst productnamen, categorieën en een vector-embedding per product op. De embedding kan worden gegenereerd op basis van de beschrijving of kenmerken van het product.

db.products.insertMany([
  {
    "name": "Smart Speaker",
    "category": "Electronics",
    "embedding": [0.8, 0.9, 0.1, ...]
  },
  {
    "name": "Wireless Earbuds",
    "category": "Electronics",
    "embedding": [0.7, 0.8, 0.2, ...]
  },
  {
    "name": "Leather Wallet",
    "category": "Fashion",
    "embedding": [0.1, 0.2, 0.9, ...]
  }
]);

Stap 2: Maak een vectorindex op embedding

db.products.createSearchIndex({
  "name": "vector_index",
  "definition": {
    "mappings": {
      "fields": [
        {
          "type": "vector",
          "path": "embedding", // The field containing the vectors
          "numDimensions": 128, // The correct field name is 'numDimensions'
          "similarity": "cosine" // The correct field name is 'similarity'
          // Index algorithm (like HNSW) is managed automatically by Atlas
        }
      ]
    }
  }
});

Stap 3: Zoek naar vergelijkbare producten

Laten we nu producten zoeken die lijken op de Smart Speaker. We gebruiken de embedding van de Smart Speaker als onze queryvector.

const smartSpeakerEmbedding = [0.8, 0.9, 0.1, ...];

db.products.aggregate([
  {
    "$vectorSearch": {
      "queryVector": smartSpeakerEmbedding,
      "path": "embedding",
      "numCandidates": 50,
      "limit": 3
    }
  },
  {
    "$project": {
      "name": 1,
      "category": 1,
      "_id": 0
    }
  }
]);

Deze query retourneert de top drie producten waarvan de vector-embeddings het dichtst bij die van de Smart Speaker liggen, en beveelt zo vergelijkbare items aan, zoals Wireless Earbuds.

Conclusie

De vectorzoekmogelijkheden van MongoDB ontsluiten nieuwe opties voor het bouwen van intelligente en gepersonaliseerde applicaties. Door vectorindexering direct in de database te integreren, vereenvoudigt MongoDB de architectuur, waardoor het beheren van data en het uitvoeren van snelle similarity searches makkelijker wordt.

Met de kracht van vector search ga je verder dan simpel trefwoordmatchen en bouw je features die de context en betekenis van je data begrijpen. We moedigen je aan om te experimenteren met de gratis MongoDB Atlas-laag en te verkennen hoe vectorindexering je applicaties kan verbeteren.

FAQs

Wat is een vector-embedding en waarom is het nodig voor vector search?

Een vector-embedding is een numerieke representatie van data zoals tekst of afbeeldingen. Het is nodig voor vector search omdat de database zo de semantische gelijkenis tussen items kan meten door de afstand tussen hun vectors te berekenen, verder dan simpel trefwoordmatchen.

Heb ik een specifieke MongoDB-versie nodig om Vector Search te gebruiken?

Ja. Vector search is een geïntegreerde feature van MongoDB Atlas, de cloud-gehoste versie van MongoDB. Het is niet beschikbaar in de community- of on-premise-edities van de database.

Moet ik zelf vector-embeddings genereren?

Ja, je moet de vector-embeddings voor je data genereren voordat je ze in MongoDB kunt opslaan en er een vectorindex voor kunt maken. MongoDB genereert deze embeddings niet voor je. Je gebruikt meestal een externe service of een voorgetraind model van een platform zoals OpenAI, Hugging Face of Google AI om je tekst, afbeeldingen of andere data om te zetten in numerieke vectors.

Kan ik vector search combineren met andere MongoDB-queries?

Ja, dat kan. Vector search is een aggregatiestap ($vectorSearch), wat betekent dat je het kunt gebruiken binnen een grotere MongoDB-aggregatiepijplijn. Hiermee kun je vector search combineren met andere krachtige stappen zoals $match, $project, $limit en $lookup om geavanceerde queries te maken die filteren, sorteren en data-verrijking uitvoeren in één bewerking. Deze mogelijkheid staat bekend als hybrid search en is essentieel voor het bouwen van toepassingen in de praktijk.

Wat is het verschil tussen de IVF- en HNSW-indextypen?

Zowel IVF als HNSW zijn algoritmen voor approximate nearest neighbor (ANN)-zoekopdrachten. Het belangrijkste verschil zit in hoe ze de data structureren.

Karen Zhang

Auteur

Karen Zhang

Karen is een Data Engineer met een passie voor het bouwen van schaalbare dataplatforms. Ze heeft ervaring met infrastructuurautomatisering met Terraform en deelt haar inzichten graag in blogposts en tutorials. Karen is een community builder en ze zet zich in om verbindingen tussen dataprofessionals te stimuleren.

Onderwerpen

Gerelateerd